PlayZoneUK Posted August 30, 2010 Posted August 30, 2010 (edited) Good afternoon, I hope someone can help me with a script I’m working on... Background: We have approximately 8000 workstation within our organisation and approximately half of them are members of a 2003 Active Directory Domain and we are trying to push the rest into the domain. Adding the workstations to the domain is not the problem, but the user profiles are… (We are talking a lot of crap here people!) A previous employee managed to achieve this process using 'moveuser.exe' which is a part of the Windows 2003 Resource Kit and a combination of registry files, batch files and an autoit script. However he didn't anticipate problems with the profiles i.e. corruption or profile locks. We have UPHClean installed on the majority of our workstations but this only seems to work if the user logs in and out again for a profile clean up. I have taken all of the above and tried to incorporate the processes into a single AutoIT Script. The script works as follows: If the ini file doesn't exist then UPMT opens the configuration GUI where you can customise the settings. Once you click OK this will generate the file (If you need to change it later on you can use the /CONFIG parameter.) If used with the /CLEAN parameter, UPMT will search for User Profiles in the following location within the registry: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList If UPMT finds a RefCount DWORD value that is set to something other than '0' then UPMT resets it. (The current user logged in is excluded) UPMT then joins the workstation to the Active Directory Domain UPMT creates an entry in RunOnce to load itself with the /MIGRATE parameter. UPMT also sets the AutoAdminLogon, DefaultUserName and DefaultPassword registry keys to allow it to perform the migration of profiles as a local administrator. UPMT imports any additional registry settings if specified e.g. For the Novell Client UPMT prompts user for a reboot. When the workstation has rebooted it will automatically login and launch UPMT with the /MIGRATE parameter which starts the migration of profiles. Once the migration is complete UPMT disables the AutoAdminLogin feature and removes the entries previously set from the registry. UPMT imports another registry file (which can undo the previous entries imported) UPMT reboots. There is another parameter /JOIN which doesn't perform the profile cleanup operation. Instead it just joins the workstation to the domain and will start the migration of profiles on next reboot. All good so far, but I would like the ability to exclude users from the migration e.g. Administrator helpdesk etc... This is the point where I'm stuck I can read the excluded users from the ini file but I can't get my head round what I need to do at this point... Thanks in advance... expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_icon=UPMT.ico #AutoIt3Wrapper_outfile=UPMT.exe #AutoIt3Wrapper_Res_Comment=This utility was created using AutoIT, created by Jonathan Bennett & the AutoIt Team and utilises a number of utilities from Microsoft e.g. moveuser.exe and netdom.exe #AutoIt3Wrapper_Res_Description=User Profile Migration Tool #AutoIt3Wrapper_Res_Fileversion=1.0.0.2 #AutoIt3Wrapper_Res_Fileversion_AutoIncrement=y ://////=__=.= ://////=__=.= ://////=__= ://////=__=... #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <WindowsConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #Include <String.au3> #include <ButtonConstants.au3> Opt('GUIOnEventMode' , 1) Opt('TrayIconHide', 1) Global $App = "User Profile Migration Tool" Global $INI_File = @ScriptDir & "\" & StringTrimRight(@ScriptName, 4) & ".ini" Global $EncryptionKey = "AUTOITRULES!" Global $guiLocalUSER, $guiLocalPWD, $guiDomainUSER, $guiDomainPWD, $guiDomain, $guiDomainOU, $guiExcluded, $guipremigrate, $guipostmigrate, $GUI If NOT FileExists($INI_File) Then _SetConfig() $message = "Please Wait..." & @CRLF & @CRLF & _ "Your account is being moved and if you attempt to close this box or reboot your PC, it will not function as expected and you are likely to lose files." & @CRLF & @CRLF & _ "Your PC will reboot itself when this process has finished." & @CRLF & @CRLF & _ "If you see this box for more than 10 minutes, please phone the helpdesk on xXXXXX and provide the following information:" & @CRLF & @CRLF & _ "Computer Name: "& @ComputerName & @CRLF & _ "IP Address: " & @IPAddress1 ; Checking for command line switches If $cmdline[0] > 0 Then Switch $cmdline[1] Case "/JOIN", "/join" _JoinDomain() Case "/CLEAN", "/clean" _CleanUpUserProfiles() Case "/MIGRATE", "/migrate" _MigrateProfiles() Case "/CONFIG", "/config" _SetConfig() Case "-?", "/?" MsgBox(0, $App & " - Help", @ScriptName & " /CONFIG = Opens configuration" & @CRLF & @CRLF & _ @ScriptName & " /CLEAN = Performs following actions:" & @CRLF & _ @TAB & "- Cleans up User Profiles" & @CRLF & _ @TAB & "- Joins workstation to domain" & @CRLF & _ @TAB & "- Migrates User Profiles" & @CRLF & @CRLF & _ @ScriptName & " /JOIN = Performs following actions:" & @CRLF & _ @TAB & "- Joins workstation to domain" & @CRLF & _ @TAB & "- Migrates User Profiles" & @CRLF & @CRLF & _ @ScriptName & " /MIGRATE = Performs following actions:" & @CRLF & _ @TAB & "- Migrates User Profiles") Exit Case Else MsgBox(0, $App & " - Invalid Parameter!", "Please use " & @ScriptName & " /? for a list of parameters") Exit EndSwitch ;~ Else ;~ MsgBox(16, $App, "Command line parameter is required!" & @CRLF & @CRLF & "Please use " & @ScriptName & " /? for a list of parameters.") ;~ Exit EndIf Func _SetConfig() $GUI = GUICreate($App, 300, 500, -1, -1, $WS_BORDER);, $WS_EX_TOOLWINDOW) ; Local Authentication Details Local $LocalUSER = IniRead($INI_File, "Local", "Username", "") Local $LocalPWD = _StringEncrypt(0, IniRead($INI_File, "Local", "Password", ""), $EncryptionKey, 1) ; Domain Name Local $Domain = IniRead($INI_File, "Domain", "Domain", "") ; Domain Organisational Unit Local $DomainOU = IniRead($INI_File, "Domain", "DomainOU", "") ; Domain Authentication Details Local $DomainUSER = IniRead($INI_File, "Domain", "Username", "") Local $DomainPWD = _StringEncrypt(0, IniRead($INI_File, "Domain", "Password", ""), $EncryptionKey, 1) Local $ExcludeUser = StringReplace(IniRead($INI_File, "ExcludeUsers", "Users", ""), "|", @CRLF) Local $PreMigrate = IniRead($INI_File, "Actions", "PreMigrate", "") Local $PostMigrate = IniRead($INI_File, "Actions", "PostMigrate", "") GuiCtrlCreateGroup("Local Credentials", 5, 5, 285, 80) GuiCtrlCreateLabel("Username:", 15, 30) $guiLocalUSER = GuiCtrlCreateInput($LocalUSER, 80, 25, 200, 20) GuiCtrlCreateLabel("Password:", 15, 55) $guiLocalPWD = GuiCtrlCreateInput($LocalPWD, 80, 50, 200, 20, $ES_PASSWORD) GuiCtrlCreateGroup("Domain Credentials", 5, 90, 285, 80) GuiCtrlCreateLabel("Username:", 15, 115) $guiDomainUSER = GuiCtrlCreateInput($DomainUSER, 80, 110, 200, 20) GuiCtrlCreateLabel("Password:", 15, 140) $guiDomainPWD = GuiCtrlCreateInput($DomainPWD, 80, 135, 200, 20, $ES_PASSWORD) GuiCtrlCreateGroup("Domain", 5, 175, 285, 80) GuiCtrlCreateLabel("Domain:", 15, 200) $guiDomain = GuiCtrlCreateInput($Domain, 80, 195, 200, 20) GuiCtrlCreateLabel("W/S OU:", 15, 225) $guiDomainOU = GuiCtrlCreateInput($DomainOU, 80, 220, 200, 20) GuiCtrlCreateGroup("Excluded User(s) from migration", 5, 260, 285, 80) $guiExcluded = GuiCtrlCreateEdit($ExcludeUser, 15, 280, 265, 50, $ES_WANTRETURN + $ES_AUTOVSCROLL ) GuiCtrlCreateGroup("Registry Changes", 5, 345, 285, 80) GuiCtrlCreateLabel("Pre-Migrate:", 15, 370) $guipremigrate = GuiCtrlCreateInput($PreMigrate, 80, 365, 170, 20) GUICtrlSetTip(-1, "Ensure that the *.reg file is located within the same location as " & @ScriptName) $btBrowse = GUICtrlCreateButton("...", 255, 365, 26, 18) GUICtrlSetOnEvent(-1,"_PreMigrateBrowse") GuiCtrlCreateLabel("Post Migrate:", 15, 395) $guipostmigrate = GuiCtrlCreateInput($PostMigrate, 80, 390, 170, 20) GUICtrlSetTip(-1, "Ensure that the *.reg file is located within the same location as " & @ScriptName) $btBrowse = GUICtrlCreateButton("...", 255, 390, 26, 18) GUICtrlSetOnEvent(-1,"_PostMigrateBrowse") $btOk = GUICtrlCreateButton("Ok", 75, 435, 70, -1, $BS_DEFPUSHBUTTON) GUICtrlSetOnEvent(-1,"_WriteConfig") $btCancel = GUICtrlCreateButton("Cancel", 155, 435, 70, -1) GUICtrlSetOnEvent(-1,"_Quit") While 1 ; Main script loop GUISetState() Sleep (10000) WEnd EndFunc Func _PreMigrateBrowse() Local $sTmpFile = FileOpenDialog("Select file:", @ScriptDir , "Registration Files (*.reg)") GUICtrlSetData($guipremigrate, StringRegExpReplace($sTmpFile, "^.+\\(.+)$", "$1")); GUI will be updated at next iteration EndFunc Func _PostMigrateBrowse() Local $sTmpFile = FileOpenDialog("Select file:", @ScriptDir , "Registration Files (*.reg)") GUICtrlSetData($guipostmigrate, StringRegExpReplace($sTmpFile, "^.+\\(.+)$", "$1")); GUI will be updated at next iteration EndFunc Func _WriteConfig() $sLocalUser = GUICtrlRead($guiLocalUSER) $sLocalPwd = _StringEncrypt(1, GUICtrlRead($guiLocalPWD), $EncryptionKey, 1) $sDomainUser = GUICtrlRead($guiDomainUSER) $sDomainPwd = _StringEncrypt(1, GUICtrlRead($guiDomainPWD), $EncryptionKey, 1) $sDomain = GUICtrlRead($guiDomain) $sDomainOU = GUICtrlRead($guiDomainOU) $sExcludeUser = StringReplace(GUICtrlRead($guiExcluded), @CRLF, "|") $sPreMigrate = GUICtrlRead($guipremigrate) $sPostMigrate = GUICtrlRead($guipostmigrate) IniWrite ($INI_File, "Actions", "PreMigrate", $sPreMigrate) IniWrite ($INI_File, "Actions", "PostMigrate", $sPostMigrate) IniWrite ($INI_File, "Local", "Username", $sLocalUser) IniWrite ($INI_File, "Local", "Password", $sLocalPwd) IniWrite ($INI_File, "Domain", "Domain", $sDomain) IniWrite ($INI_File, "Domain", "DomainOU", $sDomainOU) IniWrite ($INI_File, "Domain", "Username", $sDomainUser) IniWrite ($INI_File, "Domain", "Password", $sDomainPwd) IniWrite ($INI_File, "ExcludeUsers", "Users", $sExcludeUser) GUIDelete($GUI) Exit EndFunc Func _CleanUpUserProfiles() Local $iStart = 0, $sVal Local $sReg = "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" While 1 $iStart += 1 $sKey = RegEnumKey($sReg, $iStart) If @Error Then ExitLoop If StringMid($sKey, 7, 2) <> 21 Then ContinueLoop $sVal = RegRead($sReg & "\" & $sKey, "ProfileImagePath") $sUserProfile = StringRegExpReplace($sVal, "^.+\\(.+)$", "$1") If $sUserProfile <> @UserName Then $sRefCount=RegRead($sReg & "\" & $sKey, "RefCount") If $sRefCount <> 0 Then $sResetRefCount=RegWrite($sReg & "\" & $sKey, "RefCount", "REG_DWORD", 0) If @error <> 0 AND @error <> 1 Then MsgBox(16, $App, "An error has occurred while attempting to reset a user profile." & @CRLF & @CRLF & "User Profile: " & $sUserProfile & @CRLF & "Error Code: " & @error) EndIf WEnd _JoinDomain() EndFunc ;==>_CleanUpUserProfiles Func _JoinDomain() Local $PreMigrate = IniRead($INI_File, "Actions", "PreMigrate", "") Local $LocalUSER = IniRead($INI_File, "Local", "Username", "") Local $LocalPWD = _StringEncrypt(0, IniRead($INI_File, "Local", "Password", ""), $EncryptionKey, 1) Local $setDomainOU Local $Domain = IniRead($INI_File, "Domain", "Domain", "") Local $DomainOU = IniRead($INI_File, "Domain", "DomainOU", "") Local $DomainUSER = IniRead($INI_File, "Domain", "Username", "") Local $DomainPWD = _StringEncrypt(0, IniRead($INI_File, "Domain", "Password", ""), $EncryptionKey, 1) If $DomainOU <> "" Then $setDomainOU = " /OU:" ; Sets the Domain OU of where to add a computer account if specified within the ini file. Msgbox(0,"Debug", "netdom.exe join " & @ComputerName & " /Domain:" & $Domain & $setDomainOU & $DomainOU & " /UserD:" & $DomainUSER & " /PasswordD:" & $DomainPWD & " >C:\Migrate.log") ;~ RunWait(@Comspec & " /c netdom.exe join " & @ComputerName & " /Domain:" & $Domain & $setDomainOU & $DomainOU & " /UserD:" & $DomainUSER & " /PasswordD:" & $DomainPWD & " >C:\Migrate.log", @ScriptDir, @SW_MINIMIZE) ; RegWrite("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce", "UPMT", "REG_SZ", """" & @ScriptFullPath & """ /MIGRATE") RegWrite("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon", "AutoAdminLogon", "REG_SZ", 1) RegWrite("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon", "DefaultUserName", "REG_SZ", $LocalUSER) RegWrite("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon", "DefaultPassword", "REG_SZ", $LocalPWD) If $PreMigrate <> "" Then RunWait("regedit -s " & $PreMigrate, @ScriptDir) If (MsgBox(33, $App & " - Reboot Required", "Your computer has just joined to the " & $Domain & " domain." & @CRLF & @CRLF & "On next reboot, all user profiles (your settings) will be migrated which may take some time." & @CRLF & @CRLF & "Press OK to reboot now, or Cancel to return to Windows." & @CRLF & "If you click Cancel, please reboot over lunch or as you leave this evening.") = 1) Then MsgBox(0, "DEBUG", "Restart") ;~ Shutdown(22) ;Force or force if hung a reboot EndIf EndFunc Func _MigrateProfiles() Local $PostMigrate = IniRead($INI_File, "Actions", "PostMigrate", "") Local $Domain = IniRead($INI_File, "Domain", "Domain", "") $Domain = StringLeft($Domain, (StringInStr($Domain, ".")-1)) If $Domain <> "" Then $Domain = $Domain & "\" Else Msgbox(16, $App, "The domain has not been specified or is not fully qualified." & @CRLF & @CRLF & "Please run " & @ScriptName & " /CONFIG and make the necessary changes.") Exit EndIf Local $ExcludeUser= StringSplit(IniRead($INI_File, "ExcludeUsers", "Users", ""), "|") SplashTextOn($App, $message, -1, 220, -1, -1, 20,"Arial",10) RegDelete("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon", "AutoAdminLogon") RegDelete("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon", "DefaultPassword") If $PostMigrate <> "" Then RunWait("regedit -s " & $PostMigrate, @ScriptDir) Local $iStart = 0, $sVal Local $sReg = "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" While 1 $iStart += 1 $sKey = RegEnumKey($sReg, $iStart) If @Error Then ExitLoop If StringMid($sKey, 7, 2) <> 21 Then ContinueLoop $sVal = RegRead($sReg & "\" & $sKey, "ProfileImagePath") $sUserProfile = StringRegExpReplace($sVal, "^.+\\(.+)$", "$1") ; <====== STUCK HERE ======> ;~ If IsArray($ExcludeUser) Then ;~ For $i = 1 to $ExcludeUser[0] ;~ If $sUserProfile <> $ExcludeUser[$i] Then ;~ MsgBox(0, $App, $ExcludeUser[$i]) ;~ Next ;~ EndIf If $sUserProfile <> @UserName Then Msgbox(0,"Debug", "moveuser.exe " & $sUserProfile & " " & $Domain & $sUserProfile, @ScriptDir) ;RunWait(@Comspec & " /c moveuser.exe " & $sUserProfile & " " & $Domain & $sUserProfile, @ScriptDir) WEnd SplashOff() MsgBox(0, "DEBUG", "Restart") ;~ Shutdown(22) ;Force or force if hung a reboot Exit EndFunc Func _Quit() GUIDelete($GUI) Exit EndFunc Exit Edited August 30, 2010 by PlayZoneUK Words of Wisdom and Favourite Quotes: 'Nothing is impossible, despite what other people say and think, prove them wrong and show them what you can do!' 'Understanding is a three edged sword, your side, their side and the truth!' 'The truth that humanity has never been able to grasp, is that death may be the only absolute freedom there is!' 'I've run out of places to put the brush... what do you suggest?'
PlayZoneUK Posted August 30, 2010 Author Posted August 30, 2010 I know I can achieve my objective if I hard code the usernames into my script: If $sUserProfile <> @UserName AND $sUserProfile <> "administrator" AND $sUserProfile <> "helpdesk" Then RunWait(@Comspec & " /c moveuser.exe " & $sUserProfile & " " & $Domain & $sUserProfile, @ScriptDir) However I would like the ability to customise from an ini file incase I need to add any additional accounts in the future, I'm just not sure how to implement this... any help will be much appreciated Words of Wisdom and Favourite Quotes: 'Nothing is impossible, despite what other people say and think, prove them wrong and show them what you can do!' 'Understanding is a three edged sword, your side, their side and the truth!' 'The truth that humanity has never been able to grasp, is that death may be the only absolute freedom there is!' 'I've run out of places to put the brush... what do you suggest?'
ShawnW Posted August 30, 2010 Posted August 30, 2010 1st to answer your immediate question. each profile in the ProfileList key you are already looking at has a ProfileImagePath value with the path to the profile for each user that has logged in to the computer. Loop the ProfileList using the RegEnum functions and compare this value to your ini file values and skip over profiles you need. 2nd I'm curious about the details of the migration. I just wrote a nice migration script to eliminate Novell and migrate to a windows domain with active directory. It was a pretty brilliant script that actually assigned the old novell windows profile to the new domain user and took care of all permissions issues as well. This saved tons of time copying profiles and migrating the old ones once a new domain user has logged in. The only side effect is the users have a profile named in our old naming scheme (last name 1st initial) but login with the new AD user name (their ID). The benefits were that it was much quicker and that from a user standpoint everything looked the same, even desktop icon placement. If I can help with any of the specifics let me know.
Bert Posted August 30, 2010 Posted August 30, 2010 I'm working on it now. Give me a few minutes The Vollatran project My blog: http://www.vollysinterestingshit.com/
Bert Posted August 30, 2010 Posted August 30, 2010 (edited) OK, here is an example of getting the list of user profiles. Understand this is written for XP, so you may need to make changes for Windows 7 or Vista. You will see at the beginning of the script I put in a trap to look for the OS. In this example, I'm looking for just Windows XP.) You can add more traps for the other OSs in your environment. Anything you have listed in the INI will be EXCLUDED from the array. That way you can have a master list of profiles you do not wish to migrate. expandcollapse popup#include <Array.au3> $Q=2 ; set to 1 to write INI. Set to 2 to read INI. This is to just save you time ; writing the ini file. DIM $users[1] $search = -1 ; to allow for OS other than ones specified IF @OSVersion = "WIN_XP" then $search = FileFindFirstFile("C:\Documents and Settings\*") endif If $search = -1 Then MsgBox(0, "Error", "No files/directories matched the search pattern") Exit EndIf If $Q=1 then $x=1 While 1 $file = FileFindNextFile($search) If @error Then ExitLoop IniWrite("userlist.ini", "1", $x, $file) $x=$x+1 ConsoleWrite($file & @cr) ; shows what is found in the console area if you ; run the script in SciTE WEnd endif If $q = 2 then While 1 $file = FileFindNextFile($search) If @error Then ExitLoop _ArrayAdd($users, $file) WEnd endif FileClose($search) _ArrayDelete($users, 0) $ini = IniReadSection("userlist.ini", "1") ;If the listing is found in the INI, then ;it is remove from the array. For $i = 1 to $ini [0][0] $search = _ArraySearch($users, $ini[$i][1]) if $search <> -1 then _ArrayDelete($users, $search) Next _ArrayDisplay($users) ;list of users who meet the criteria. For $r = 0 to UBound($users) $sUserProfile = $users ;so you can reference the variable in your script RunWait(@Comspec & " /c moveuser.exe " & $sUserProfile & " " & $Domain & $sUserProfile, @ScriptDir) next Edited August 30, 2010 by MPH The Vollatran project My blog: http://www.vollysinterestingshit.com/
PlayZoneUK Posted August 30, 2010 Author Posted August 30, 2010 @MFH Thanks for pointing me in the right direction MFH, I believe I can incorporate some of the features within the example into my script. I'll give it ago tomorrow when I get into work and post the results / the finished product. @ShawnW Our organisation was purely a Novell eDirectory site, we utilised Novell ZENworks 6.5 for Desktops to create Dynamic Local User Profiles on the workstations. A 2003 Active Directory Domain was implemented approximately 6 years ago. Recently there has been a push to get all of our workstations into the domain, to help achieve this objective some workstations have been replaced or re-imaged. However some workstations which don't warrant replacement and can't be re-imaged (for what ever reason) have been added to the domain manually but the users loose their settings. Hence the creation of the User Profile Migration Tool I'm working on. It looks like we'll be keeping Novell for the moment as we are utilising Novell's Identity Manager solution to synchronise the usernames and passwords between eDirectory and Active Directory therefore our naming conversion remains the same for our usernames (last name and 1st initial) Since you've already experienced this issue and have created some scripts in order to resolve it, would it be possible to have a look at them to point me in the right direction and ensure I'm on the right track? Words of Wisdom and Favourite Quotes: 'Nothing is impossible, despite what other people say and think, prove them wrong and show them what you can do!' 'Understanding is a three edged sword, your side, their side and the truth!' 'The truth that humanity has never been able to grasp, is that death may be the only absolute freedom there is!' 'I've run out of places to put the brush... what do you suggest?'
ShawnW Posted August 30, 2010 Posted August 30, 2010 I'll post some code tomorrow on how look up a domain users sid, assign the domain user to an existing physical profile, and then resolve the permissions issues involved with this. This will allow a user to seemlessly transfer to the domain and start logging in with those credentials but still use the same profile they were using before. I would do it now but I gotta leave, and can't blindly post the source without making sure it doesn't reveal anything job sensitive.
PlayZoneUK Posted August 31, 2010 Author Posted August 31, 2010 @ShawnW that would be fantastic if you could it would really help me out of a bind Words of Wisdom and Favourite Quotes: 'Nothing is impossible, despite what other people say and think, prove them wrong and show them what you can do!' 'Understanding is a three edged sword, your side, their side and the truth!' 'The truth that humanity has never been able to grasp, is that death may be the only absolute freedom there is!' 'I've run out of places to put the brush... what do you suggest?'
ShawnW Posted August 31, 2010 Posted August 31, 2010 Okay here it goes. Meant to post this eariler but forgot about a meeting in the morning.The basic concept is...To figure out what sid a user will have on the new domain, and replace their current ProfileList entry with that value. This lets the user login after a domain migration and get the same profile they had before. Lots of little things like permissions need to be handled as well.External programs/scripts I used:reg.au3 by Erik Pilsits (can be found in these forums).SetAcl (google it).psgetsid from the PSTools set of utilities (google it).icacls (unnecessary with SetAcl but I commented why I used this).Notes:This was done on Windows XP SP3 machines.Just use it as a guide since I wrote it specificlly for our unique setup, it won't run for anyone as is.expandcollapse popupLogger("--- Transferring profiles Loop ---","_step2") $n=1 $ProfileList = "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\" ;======================================== ;= Loop through ProgileList in registry = ;======================================== While True ;================= ;= Read Registry = ;================= $regSID = RegEnumKey($ProfileList,$n) ; Read next local profile from registry If @error Then ExitLoop ; Exit loop if no more profile subkeys $profilePath = RegRead($ProfileList & $regSID, "ProfileImagePath") ; Read the profiles path ;================================================================================== ;= If the profile sid does not contain the sid from UNT domain... = ;= 1) Match the old user name to a new one. = ;= 2) Get the UNT domain sid for the new user name. = ;= 3) Rename(Move) the old sid named key to the new sid key for the UNT domain. = ;= 4) Change the binary sid value of this ley. = ;= 5) Give permissions for domain user to proper registry areas = ;================================================================================== If Not StringInStr($regSID,"3676313182-2055043702-2189418671") Then ; The number is the 3 sets of the user sid after S-1-5-21- $NovellUser = StringRegExp($profilePath,".*\\(.*)",1) ; Get the Novell user name from the end of the profile path $euid = GetEUID($NovellUser[0]) ; Match the Novell user with their EUID $sid = "" ; Default $sid Logger("-- Processing user profile " & $NovellUser[0] & " --","_step2") If $euid <> "-na-" Then Logger("Matched Novell user profile " & $NovellUser[0] & " to UNT user name " & $euid,"_step2") ;=========================================================== ;= Set Permissions for new user name on old user directory = ;=========================================================== Logger'Setting permissions for new user name on old user directory',"_step2") RunWait('p:\Faculty\Util\icacls.exe "' & $profilePath & '" /Grant:r UNT\' & $euid & ':(OI)(CI)F') ; ...I know I could use setacl here since I use it later for the registry, but I already had this written ; when I discovered I needed to change registry permissions and didn't feel like going back to change it. ;============================================================ ;= Get the UNT domain SID for the matched EUID as user name = ;============================================================ $sid = GetSID($euid) If $sid Then Logger("Found UNT domain SID for " & $euid & " (" & $sid & ")","_step2") Else Logger("### ERROR ### - Cound not find UNT domain SID for " & $euid,"_step2") EndIf ;====================================================================== ;= If the unt domain profile for the found sid does not already exist = ;====================================================================== If Not _RegKeyExists($ProfileList & $sid) Then ;=============================================================== ; Transfer the current profile to its matching unt domain user = ; by moveing the old user SID registry key to the new UNT one = ;=============================================================== Logger("Transferring the current profile for " & $NovellUser[0] & " to UNT\" & $euid,"_step2") _RegMoveKey($ProfileList & $regSID,$ProfileList & $sid) ;================================================================================================================= ;= ... When we ran this script I noticed that _RegMoveKey was not actually deleting old key as expected. = ;= I didn't think this was a problem until a few users started accidently logging into their old account. = ;= I would recommend making sure the old key is gone at this point. But who knows the function may work for you. = ;================================================================================================================= ;==================================================================== ;= Update the binary Sid registry value for the transferred profile = ;==================================================================== Logger("Updating the binary Sid value for the transferred profile","_step2") $userSidSegment = StringRegExp($sid,".*-(.*)",1) ; Get the last part of the sid which identifies a user $hex = Hex($userSidSegment[0]) ; Transform this into a Hexadecimal number $hexString = StringRight($hex,2) & StringMid($hex,5,2) & StringMid($hex,3,2) & StringLeft($hex,2) ; Reverse the Hex, 2 bits at a time Ex. 12345678 -> 78563412 RegWrite($ProfileList & $sid,"Sid","REG_BINARY","0x0105000000000005150000005E1620DB767A7D7AAFE07F82" & $hexString) ; ...The 1st part of that string I copied from another user already created on that domain. ; It will be the same for all users in the domain and only the last 8 digits refer to the user. ;================================== ;= Load user hive to the registry = ;================================== $tempKey = "HKEY_USERS\temp" Logger("Loading the user hive Located in " & $profilePath & "\NTUSER.DAT") RunWait(@comspec & ' /c reg load HKU\Temp "' & $profilePath & '\NTUSER.DAT"') ;================================= ;= Give registry key permissions = ;================================= Logger("Giving UNT\" & $euid & " Full permissions to the loaded user hive") RunWait(@comspec & ' /c P:\Faculty\Batch\SetACL.exe -on "\\' & @ComputerName & '\' & $tempKey & '" -ot reg -actn ace -ace "n:UNT\' & $euid & ';p:full" -rec yes') Logger("Giving UNT\" & $euid & " Special permissions to " & $ProfileList & $sid,"_step2") RunWait(@comspec & ' /c P:\Faculty\Util\SetACL.exe -on "\\' & @ComputerName & '\' & $ProfileList & $sid & '" -ot reg -actn ace -ace "n:UNT\' & $euid & ';p:query_val,set_val,create_subkey,enum_subkeys,notify,create_link,delete,read_access" -rec yes') ; ...Removed some code others probably wont need that removes any persistant, user mapped, network drives to locations on our old servers. ;==================== ;= Unload user hive = ;==================== Logger("Unloading the user hive","_step2") RunWait(@comspec & ' /c reg unload HKU\Temp') Else Logger("### NOTICE ### - Registry key already exists (" & $ProfileList & $sid & ")","_step2") EndIf Else Logger("### ERROR ### - No matching UNT domain user name for Novell user profile " & $NovellUser[0],"_step2") EndIf Logger("-- Completed " & $NovellUser[0] & " --","_step2") EndIf $n += 1 WEnd Logger("--- End Transferring profiles Loop ---","_step2") Logger("----- Migration Step 2 Completed! Restarting Computer -----","_step2") MsgBox(0,"Shutdown","System Restarting in 5 seconds.",5) Shutdown(2) ;============================================================================================================ ;==== ADDITINAL FUNCTIONS ==== ;============================================================================================================ ; Logger calls a logger script we created to standardize our log format and location for all scripts. ; It also displays a tooltip in the corner to let the person running the scipt easily track it's progress. Func Logger($text,$LogNameAppend="") $directory="Novell Migration\" If $text = "" Then Return ToolTip($text,0,0) RunWait("\\cob-static\apps\Faculty\Batch\logger.exe """ & $text & """ """ & $directory & @ComputerName & $LogNameAppend & ".txt""") EndFunc ; GetEUID looks at a previously generated text file with matches for old to new names. ; All new user names are the users euid except multi-user accounts. Func GetEUID($userName) $userName = StringRegExpReplace($userName,"\..*","") If StringRegExp($userName,"^[a-zA-z]{2,3}\d{4}$") Then Return $userName $file = FileRead("N:\Scripts\Novell2EUID.txt") $userMatch = StringRegExp($file, "(?i)" & $userName & ",(.*?)\r\n",1) If @error Then Return "-na-" Return $userMatch[0] EndFunc ; GetSID uses a Pstools utility psgetsid to look up the sid for an existing UNT domain user. ; The user needs to have been created on the domain but does not need to have logged into any computer. Func GetSID($userEUID) ;~ If $userEUID = "LocalSupport" Then Return "S-1-5-21-1731668739-84674044-697575874-1093" ; ...Commented this out for forum post because I honestly can't remember why I needed this exception, but noting exceptions might be required. $temp = @TempDir & "\temp.txt" RunWait(@ComSpec & ' /c ' & 'N:\SUPER\UTILITY\Pstools\psgetsid UNT\' & $userEUID & ' > ' & $temp,'',@SW_HIDE) $sid = FileReadLine($temp,2) If StringLeft($sid,9) <> "S-1-5-21-" Then $sid = "" ; Validate SID If FileExists($temp) Then FileDelete($temp) Return $sid EndFunc
PlayZoneUK Posted September 2, 2010 Author Posted September 2, 2010 Sorry for not replying to you sooner ShawnW... Thank you for posting your script I will use it as a guide as you suggested. As previously posted we haven't changed our naming convention so it doesn't need to be advanced as yours ... Fortunately the moveuser.exe utility which comes with the Windows 2003 Resource Kit sorts out the permissions issues so I don't have to utilise any other utilities. NOTE: Our target OS = Windows XP Service Pack 3 Hopefully I'll post the finished product in a few days Words of Wisdom and Favourite Quotes: 'Nothing is impossible, despite what other people say and think, prove them wrong and show them what you can do!' 'Understanding is a three edged sword, your side, their side and the truth!' 'The truth that humanity has never been able to grasp, is that death may be the only absolute freedom there is!' 'I've run out of places to put the brush... what do you suggest?'
robin850 Posted October 8, 2010 Posted October 8, 2010 Sorry for not replying to you sooner ShawnW...Thank you for posting your script I will use it as a guide as you suggested. As previously posted we haven't changed our naming convention so it doesn't need to be advanced as yours ... Fortunately the moveuser.exe utility which comes with the Windows 2003 Resource Kit sorts out the permissions issues so I don't have to utilise any other utilities.NOTE: Our target OS = Windows XP Service Pack 3Hopefully I'll post the finished product in a few daysAny luck with this? i am very interested in seeing your final results.cheers,robin850
PlayZoneUK Posted November 28, 2010 Author Posted November 28, 2010 Any luck with this? i am very interested in seeing your final results.cheers,robin850Sorry robin850 I've just seen your post. The source code is on my network drive at work, I will post it tomorrow for those of you who are interested... Words of Wisdom and Favourite Quotes: 'Nothing is impossible, despite what other people say and think, prove them wrong and show them what you can do!' 'Understanding is a three edged sword, your side, their side and the truth!' 'The truth that humanity has never been able to grasp, is that death may be the only absolute freedom there is!' 'I've run out of places to put the brush... what do you suggest?'
PlayZoneUK Posted March 15, 2011 Author Posted March 15, 2011 Sorry for the long delay... enjoy expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_icon=UPMT.ico #AutoIt3Wrapper_outfile=UPMT.exe #AutoIt3Wrapper_Res_Comment=This utility was created using AutoIT, created by Jonathan Bennett & the AutoIt Team and utilises a number of utilities from Microsoft e.g. moveuser.exe and netdom.exe #AutoIt3Wrapper_Res_Description=User Profile Migration Tool #AutoIt3Wrapper_Res_Fileversion=1.0.0.99 #AutoIt3Wrapper_Res_Fileversion_AutoIncrement=y #AutoIt3Wrapper_Res_LegalCopyright=© 2010 PlayZoneUK ://////=__=.= ://////=__=.= ://////=__= ://////=__=... #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <WindowsConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #Include <String.au3> #include <ButtonConstants.au3> #include <Array.au3> #include <Process.au3> #Include <Date.au3> #include <ProgressConstants.au3> Opt('GUIOnEventMode' , 1) #NoTrayIcon Global $App = "User Profile Migration Tool" Global $INI_File = @ScriptDir & "\" & StringTrimRight(@ScriptName, 4) & ".ini" Global $EncryptionKey = "AUTOITRULES" Global $guiLocalUSER, $guiLocalPWD, $guiDomainUSER, $guiDomainPWD, $guiDomain, $guiDomainOU, $guiExcluded, $guipremigrate, $guipostmigrate, $GUI DIM $IncludeUser[1] If NOT FileExists($INI_File) Then _SetConfig() $message = "The user profiles on this workstation are migrating to the domain (your settings)..." & @CRLF & @CRLF & _ "WARNING:" & @CRLF &"If you attempt to close this box or reboot your PC, it will not function as expected and you are likely to lose files." & @CRLF & @CRLF & _ "Your PC will automatically reboot itself when this process has finished." & @CRLF & @CRLF & _ "It is likely that this process will take 10 minutes per profile. If it appears to be taking longer, please phone the helpdesk on x26655 and provide the following information:" & @CRLF & @CRLF & _ "Computer Name: "& @ComputerName & @CRLF & _ "IP Address: " & @IPAddress1 If @OSVersion <> "WIN_XP" Then Msgbox(16, $App, "The " & $App & " has been designed for Microsoft Windows XP only." & @CRLF & @CRLF & "Please contact your system administrator.", 30) Exit EndIf ; Checking for command line switches If $cmdline[0] > 0 Then Switch $cmdline[1] Case "/JOIN", "/join" _JoinDomain() Case "/CLEAN", "/clean" _CleanUpUserProfiles() Case "/MIGRATE", "/migrate" _MigrateProfiles() Case "/CONFIG", "/config" _SetConfig() Case "-?", "/?" MsgBox(0, $App & " - Help", @ScriptName & " /CONFIG = Opens configuration" & @CRLF & @CRLF & _ @ScriptName & " /CLEAN = Performs following actions:" & @CRLF & _ @TAB & "- Cleans up User Profiles" & @CRLF & _ @TAB & "- Joins workstation to domain" & @CRLF & _ @TAB & "- Migrates User Profiles" & @CRLF & @CRLF & _ @ScriptName & " /JOIN = Performs following actions:" & @CRLF & _ @TAB & "- Joins workstation to domain" & @CRLF & _ @TAB & "- Migrates User Profiles" & @CRLF & @CRLF & _ @ScriptName & " /MIGRATE = Performs following actions:" & @CRLF & _ @TAB & "- Migrates User Profiles") Exit Case Else MsgBox(0, $App & " - Invalid Parameter!", "Please use " & @ScriptName & " /? for a list of parameters") Exit EndSwitch EndIf Func _SetConfig() $GUI = GUICreate($App, 300, 500, -1, -1, $WS_BORDER);, $WS_EX_TOOLWINDOW) ; Local Authentication Details Local $LocalUSER = IniRead($INI_File, "Local", "Username", "") Local $LocalPWD = _StringEncrypt(0, IniRead($INI_File, "Local", "Password", ""), $EncryptionKey, 1) ; Domain Name Local $Domain = IniRead($INI_File, "Domain", "Domain", "") ; Domain Organisational Unit Local $DomainOU = IniRead($INI_File, "Domain", "DomainOU", "") ; Domain Authentication Details Local $DomainUSER = IniRead($INI_File, "Domain", "Username", "") Local $DomainPWD = _StringEncrypt(0, IniRead($INI_File, "Domain", "Password", ""), $EncryptionKey, 1) Local $ExcludedUser = "" Local $PreMigrate = IniRead($INI_File, "Actions", "PreMigrate", "") Local $PostMigrate = IniRead($INI_File, "Actions", "PostMigrate", "") GuiCtrlCreateGroup("Local Credentials", 5, 5, 285, 80) GuiCtrlCreateLabel("Username:", 15, 30) $guiLocalUSER = GuiCtrlCreateInput($LocalUSER, 80, 25, 200, 20) GuiCtrlCreateLabel("Password:", 15, 55) $guiLocalPWD = GuiCtrlCreateInput($LocalPWD, 80, 50, 200, 20, $ES_PASSWORD) GuiCtrlCreateGroup("Domain Credentials", 5, 90, 285, 80) GuiCtrlCreateLabel("Username:", 15, 115) $guiDomainUSER = GuiCtrlCreateInput($DomainUSER, 80, 110, 200, 20) GuiCtrlCreateLabel("Password:", 15, 140) $guiDomainPWD = GuiCtrlCreateInput($DomainPWD, 80, 135, 200, 20, $ES_PASSWORD) GuiCtrlCreateGroup("Domain", 5, 175, 285, 80) GuiCtrlCreateLabel("Domain:", 15, 200) $guiDomain = GuiCtrlCreateInput($Domain, 80, 195, 200, 20) GuiCtrlCreateLabel("W/S OU:", 15, 225) $guiDomainOU = GuiCtrlCreateInput($DomainOU, 80, 220, 200, 20) GuiCtrlCreateGroup("Excluded User(s) from migration", 5, 260, 285, 80) $guiExcluded = GuiCtrlCreateEdit("Please configure the ini file manually for Excluded Users", 15, 280, 265, 50, $ES_WANTRETURN + $ES_AUTOVSCROLL ) ;~ GUICtrlSetTip(-1, "Please configure the ini file manually for Excluded Users") GUICtrlSetState(-1, $GUI_DISABLE) GuiCtrlCreateGroup("Registry Changes", 5, 345, 285, 80) GuiCtrlCreateLabel("Pre-Migrate:", 15, 370) $guipremigrate = GuiCtrlCreateInput($PreMigrate, 80, 365, 170, 20) GUICtrlSetTip(-1, "Ensure that the *.reg file is located within the same location as " & @ScriptName) $btBrowse = GUICtrlCreateButton("...", 255, 365, 26, 18) GUICtrlSetOnEvent(-1,"_PreMigrateBrowse") GuiCtrlCreateLabel("Post Migrate:", 15, 395) $guipostmigrate = GuiCtrlCreateInput($PostMigrate, 80, 390, 170, 20) GUICtrlSetTip(-1, "Ensure that the *.reg file is located within the same location as " & @ScriptName) $btBrowse = GUICtrlCreateButton("...", 255, 390, 26, 18) GUICtrlSetOnEvent(-1,"_PostMigrateBrowse") $btOk = GUICtrlCreateButton("Ok", 75, 435, 70, -1, $BS_DEFPUSHBUTTON) GUICtrlSetOnEvent(-1,"_WriteConfig") $btCancel = GUICtrlCreateButton("Cancel", 155, 435, 70, -1) GUICtrlSetOnEvent(-1,"_Quit") While 1 ; Main script loop GUISetState() Sleep (10000) WEnd EndFunc Func _PreMigrateBrowse() Local $sTmpFile = FileOpenDialog("Select file:", @ScriptDir , "Registration Files (*.reg)") GUICtrlSetData($guipremigrate, StringRegExpReplace($sTmpFile, "^.+\\(.+)$", "$1")); GUI will be updated at next iteration EndFunc Func _PostMigrateBrowse() Local $sTmpFile = FileOpenDialog("Select file:", @ScriptDir , "Registration Files (*.reg)") GUICtrlSetData($guipostmigrate, StringRegExpReplace($sTmpFile, "^.+\\(.+)$", "$1")); GUI will be updated at next iteration EndFunc Func _WriteConfig() $sLocalUser = GUICtrlRead($guiLocalUSER) $sLocalPwd = _StringEncrypt(1, GUICtrlRead($guiLocalPWD), $EncryptionKey, 1) $sDomainUser = GUICtrlRead($guiDomainUSER) $sDomainPwd = _StringEncrypt(1, GUICtrlRead($guiDomainPWD), $EncryptionKey, 1) $sDomain = GUICtrlRead($guiDomain) $sDomainOU = GUICtrlRead($guiDomainOU) $sExcludeUser = GUICtrlRead($guiExcluded) $sPreMigrate = GUICtrlRead($guipremigrate) $sPostMigrate = GUICtrlRead($guipostmigrate) IniWrite ($INI_File, "Actions", "PreMigrate", $sPreMigrate) IniWrite ($INI_File, "Actions", "PostMigrate", $sPostMigrate) IniWrite ($INI_File, "Local", "Username", $sLocalUser) IniWrite ($INI_File, "Local", "Password", $sLocalPwd) IniWrite ($INI_File, "Domain", "Domain", $sDomain) IniWrite ($INI_File, "Domain", "DomainOU", $sDomainOU) IniWrite ($INI_File, "Domain", "Username", $sDomainUser) IniWrite ($INI_File, "Domain", "Password", $sDomainPwd) GUIDelete($GUI) Exit EndFunc Func _CleanUpUserProfiles() Local $iStart = 0, $sVal Local $sReg = "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" While 1 $iStart += 1 $sKey = RegEnumKey($sReg, $iStart) If @Error Then ExitLoop If StringMid($sKey, 7, 2) <> 21 Then ContinueLoop $sVal = RegRead($sReg & "\" & $sKey, "ProfileImagePath") ;~ MsgBox(0, "DEBUG", $sVal) $sUserProfile = StringRegExpReplace($sVal, "^.+\\(.+)$", "$1") If $sUserProfile <> @UserName Then $sRefCount=RegRead($sReg & "\" & $sKey, "RefCount") If $sRefCount <> 0 Then $sResetRefCount=RegWrite($sReg & "\" & $sKey, "RefCount", "REG_DWORD", 0) If @error <> 0 AND @error <> 1 Then MsgBox(16, $App, "An error has occurred while attempting to reset a user profile." & @CRLF & @CRLF & "User Profile: " & $sUserProfile & @CRLF & "Error Code: " & @error) WEnd _JoinDomain() EndFunc ;==>_CleanUpUserProfiles Func _JoinDomain() Local $PreMigrate = IniRead($INI_File, "Actions", "PreMigrate", "") Local $LocalUSER = IniRead($INI_File, "Local", "Username", "") Local $LocalPWD = _StringEncrypt(0, IniRead($INI_File, "Local", "Password", ""), $EncryptionKey, 1) Local $setDomainOU Local $Domain = IniRead($INI_File, "Domain", "Domain", "") Local $DomainOU = IniRead($INI_File, "Domain", "DomainOU", "") Local $DomainUSER = IniRead($INI_File, "Domain", "Username", "") Local $DomainPWD = _StringEncrypt(0, IniRead($INI_File, "Domain", "Password", ""), $EncryptionKey, 1) If $DomainOU <> "" Then $setDomainOU = " /OU:" ; Sets the Domain OU of where to add a computer account if specified within the ini file. RunWait(@Comspec & " /c netdom.exe join " & @ComputerName & " /Domain:" & $Domain & $setDomainOU & $DomainOU & " /UserD:" & $DomainUSER & " /PasswordD:" & $DomainPWD & " > C:\UPMT.log", @ScriptDir, @SW_MINIMIZE) ; Joins workstations to domain and assigns it to correct OU RegWrite("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce", "UPMT", "REG_SZ", """" & @ScriptFullPath & """ /MIGRATE") ; Adds registry entry to RunOnce part of registry to start User Profile migration after reboot RegWrite("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon", "AutoAdminLogon", "REG_SZ", 1) ; Sets AutoAdminLogon within registry RegWrite("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon", "DefaultUserName", "REG_SZ", $LocalUSER) ; Sets DefaultUserName within registry RegWrite("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon", "DefaultPassword", "REG_SZ", $LocalPWD) ; Sets DefaultPassword within registry If $PreMigrate <> "" Then RunWait("regedit -s " & $PreMigrate, @ScriptDir) If (MsgBox(33, $App & " - Reboot Required", "Your computer has just joined to the " & $Domain & " domain." & @CRLF & @CRLF & "On next reboot, all user profiles (your settings) will be migrated which may take some time." & @CRLF & @CRLF & "Press OK to reboot now, or Cancel to return to Windows." & @CRLF & "If you click Cancel, please reboot over lunch or as you leave this evening.") = 1) Then Shutdown(22) ;Force or force if hung a reboot EndIf EndFunc Func _MigrateProfiles() Local $profileCount = 1 ; Sets $ProfileCount variable Local $percent_value = 0 ; Sets $Percent_Value variable Local $ProfileAgeLimit = IniRead($INI_File, "Actions", "ProfileAgeLimit", "") ; Reads ProfileAgeLimit from ini file Local $PostMigrate = IniRead($INI_File, "Actions", "PostMigrate", "") ; Reads Post Migration Registry File name from ini file Local $Domain = IniRead($INI_File, "Domain", "Domain", "") ; Reads Domain Name from ini file $Domain = StringLeft($Domain, (StringInStr($Domain, ".")-1)) If $Domain <> "" Then $Domain = $Domain & "\" Else Msgbox(16, $App, "The domain has not been specified or is not fully qualified." & @CRLF & @CRLF & "Please run " & @ScriptName & " /CONFIG and make the necessary changes.") Exit EndIf Local $ExcludeUserList = IniReadSection($INI_File, "ExcludeUsers") ; Reads a list of excluded users specified within the ini file RegDelete("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon", "AutoAdminLogon") ; Removes AutoAdminLogon within registry RegDelete("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon", "DefaultPassword") ; Removes DefaultPassword within registry If $PostMigrate <> "" Then RunWait("regedit -s " & $PostMigrate, @ScriptDir) ; Imports registry file if specified within ini file Local $iStart = 0, $sVal Local $sReg = "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" ; Location within the registry to read While 1 $iStart += 1 $sKey = RegEnumKey($sReg, $iStart) If @Error Then ExitLoop If StringMid($sKey, 7, 2) <> 21 Then ContinueLoop $sVal = RegRead($sReg & "\" & $sKey, "ProfileImagePath") ; Obtains profile path from registry key $UserProfileList = StringRegExpReplace($sVal, "^.+\\(.+)$", "$1") ; Regular expression to remove full path and obtain username _ArrayAdd($IncludeUser,$UserProfileList) ; Adds value to Array WEnd _ArrayDelete($IncludeUser, 0) ; Deletes Array For $i = 1 to $ExcludeUserList [0][0] $UserProfileList = _ArraySearch($IncludeUser, $ExcludeUserList[$i][1]) ; Searching the array for a match if $UserProfileList <> -1 then _ArrayDelete($IncludeUser, $UserProfileList) ; If a match is found delete the entry Next $GUI = GUICreate($App, 600, 250, -1, -1, BitOR($WS_CAPTION, $WS_POPUP, $WS_BORDER, $WS_CLIPSIBLINGS), $WS_EX_WINDOWEDGE) ; Creates GUI Window GUISetFont(12, 800, 2, "Arial") ; Sets Font to size 2 and BOLD $Label1 = GUICtrlCreateLabel("Please Wait...", 10, 10, 580, 20) ; Creates Label 1 GUISetFont(8.5, 400, 0, "Arial") ; Sets Font to default $Label2 = GUICtrlCreateLabel($message, 10, 30, 580, 190) ; Creates Label 2 $Progress = GUICtrlCreateProgress(10, 210, 580, 15, $PBS_SMOOTH) ; Creates Progress Bar GUICtrlSetColor($Progress, 0xff0000) ; Sets Progress Bar Colour $Label3 = GUICtrlCreateLabel("Migrating User Profile: <OBTAINING DATA>", 10, 230, 580, 20) ; Creates Label 3 GUISetState() ; Set GUI State For $r = 0 to UBound($IncludeUser)-1 $percent_value = ($profileCount / UBound($IncludeUser)) *100 ; Calculates Percentage GUICtrlSetData($Label3, "Migrating User Profile: " & $IncludeUser[$r] & " (" & $profileCount & " of " & UBound($IncludeUser) & ")") ; Updates Label with data from variables GUICtrlSetData($Progress, $percent_value) ; Sets Progress Bar percentage $sUser = $IncludeUser[$r] ; Assigns value of array to variable $ProfileDate = FileGetTime("C:\Documents and Settings\" & $sUser & "\NTUSER.DAT", 0) ; Gets Modification Time If Not @error Then $ProfileModificationTime = $ProfileDate[0] & "/" & $ProfileDate[1] & "/" & $ProfileDate[2] ; Converts date into date format YYYYMMDD $ProfileAge = _DateDiff( 'D',$ProfileModificationTime,_NowCalc()) ; Calculates the number of days since the profile was last modified If $ProfileAge <= $ProfileAgeLimit AND $ProfileAgeLimit <> "" Then RunWait(@Comspec & " /c moveuser.exe " & $sUser & " " & $Domain & $sUser & " >> C:\UPMT.log", @ScriptDir, @SW_MINIMIZE) ; Command used if Profile Age Limit is specified within ini file If $sUser <> "Administrator" Then RunWait(@Comspec & " /c net localgroup ""Administrators"" " & $sUser & " /delete >> C:\UPMT.log", @ScriptDir, @SW_MINIMIZE) ; If user is not Administrator then removes Local / Domain User from Local Administrators Group RunWait(@Comspec & " /c net localgroup ""Power Users"" " & $sUser & " /delete >> C:\UPMT.log", @ScriptDir, @SW_MINIMIZE) ; Removes Local / Domain User from Local Power Users Group RunWait(@Comspec & " /c net localgroup ""Users"" " & $Domain & $sUser & " /delete >> C:\UPMT.log", @ScriptDir, @SW_MINIMIZE) ; Removes Domain User from Local Users Group EndIf $profileCount +=1 ; Increments $profileCount by 1 Next Shutdown(22) ;Force or force if hung a reboot Sleep(10000) ; Pauses script for 10 seconds EndFunc Func _Quit() GUIDelete($GUI) ; Deletes GUI Window(s) Exit ; Exits Script EndFunc Exitpleasant tool update Words of Wisdom and Favourite Quotes: 'Nothing is impossible, despite what other people say and think, prove them wrong and show them what you can do!' 'Understanding is a three edged sword, your side, their side and the truth!' 'The truth that humanity has never been able to grasp, is that death may be the only absolute freedom there is!' 'I've run out of places to put the brush... what do you suggest?'
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now