Guest gamackey1337 Posted May 5, 2004 Posted May 5, 2004 (edited) Here is an AutoIt v3 script I wrote for migrating user's locally stored profiles when switching to a new domain. This ensures they lose NONE of their stored settings, background, desktop stuff.....everything in their profile is migrated (except stored passwords linked to their SID in the old domain). Sorry about the tabs in the first part of the file.....I'm not sure if those will look right in this post.expandcollapse popup; ----------------------------------------------------------------------------------------- ; ; Script Name: Migrate_Profile.au3 ; ; Author: Greg Mackey <gmackey@ucok.edu> ; ; Supported OS: Windows 2000/XP ; ; Other Requirements: Windows Script 5.6 ; ; Script Function: Ensures that the user's locally stored profile remains fully intact ; when migrating from the UCO_SNA domain to the UCOK domain. ; ; Parameters: "<script name>" - Runs script with initial prompt. ; "<script name> 1" - Runs script without initial prompt. ; ; Changelog: (See "readme.txt" for changelog) ; ; ----------------------------------------------------------------------------------------- ; ========================================================================================= ; ; NOTE TO TECHS: DO NOT EDIT THIS SCRIPT. This is being provided for reference ; purposes only. The parameters that can be edited are now stored in ; the text file "parameters.txt". This means you don't need to ; compile this script or anything...just configure the text file if ; you desire and run the executable. ; ; ========================================================================================= ; Opens "parameters.txt" file for reading $parameters = FileOpen(@ScriptDir & "\parameters.txt", 0) ; Declares global variable for generic error message ; Users see this message if the script encounters an error ; Each tech support area can customize this message for their users ; Line 6 of "parameters.txt" must be edited if a custom error message is desired Global $errormsg = @CRLF & @CRLF & FileReadLine($parameters, 6) ; Declares global variable for e-mail account that should receive error notices ; If script encounters error, e-mail with error info, user name, and computer is sent ; Each tech support area can use their own e-mail address for tracking errors ; Line 15 of "parameters.txt" must be edited if a custom e-mail address is desired Global $error_email = FileReadLine($parameters, 15) ; Closes "parameters.txt" file FileClose($parameters) ; Generic UCOK domain user account ; Used for general operations when a second account is needed Global $ucok_user = "MigrateProfile" Global $ucok_user_password = "********" ; Account that belongs to ISTS group (both domains) ; Used for operations that need higher-level domain permissions Global $admin_user = "Installer_ISTS" Global $admin_user_password = "********" ; Calls function based on parameters used with script Select ; Script was started by double-clicking Case $CmdLine[0] == 0 Interactive() Case $CmdLine[1] == 1 User1() Case $CmdLine[1] == 2 User2($CmdLine[2]) Case $CmdLine[1] == 3 MigrateProfile($CmdLine[2], $CmdLine[3]) Case $CmdLine[1] == 4 Cleanup($CmdLine[2]) EndSelect Func Interactive() ; Verifies user wishes to migrate profile $answer = MsgBox(36, "Migrate Profile?", "Do you wish to migrate your user profile _ at this time?") ; Script continues or exits based on option chosen (YES or NO) If $answer = 6 Then User1() Else Exit EndIf EndFunc Func User1() ; Verifies user is in local Administrators group If NOT IsAdmin() Then Error("NotAdmin", @UserName) EndIf ; Verifies OS is Windows 2000 or XP If @OSVersion <> "WIN_2000" AND @OSVersion <> "WIN_XP" Then Error("WrongOS", @UserName) EndIf ; Verifies user is logged into UCO_SNA domain If @LogonDomain <> "UCO_SNA" Then Error("WrongDomain", @UserName) EndIf ; Deletes old/temp files CreateFreeSpace() ; Installs Windows Script 5.6.0.8515 if necessary If FileGetVersion(@SystemDir & "\wscript.exe") <> "5.6.0.8515" Then RunWait(@ScriptDir & "\ws56.exe /Q:A /R:N") EndIf ; Determines current profile size CheckProfileSize() EndFunc Func User2($profilesize) ; Verifies enough free space exists for profile copy VerifySpace($profilesize) ; Verifies identical user account exists in UCOK domain based on current user name CheckForUser() ; Prepares computer to log in as generic UCOK user for profile copy operation CopyPrep() ; Reboots computer in order to ensure the user's profile is not locked Shutdown(6) EndFunc Func MigrateProfile($userprofile, $user) ; Verifies correct user is logged on If @UserName <> $ucok_user Then ReverseMigrate("Migrate_WrongUser", $user) EndIf ; Gets security ID of user's UCO_SNA account $sid = GetSid($user) ; Gets profile path of user's UCO_SNA account using SID $newprofilepath = GetProfilePath($sid, $user) ; Reads "Default User" folder name from registry $default_user_folder = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows _ NT\CurrentVersion\ProfileList", "DefaultUserProfile") ; Renames "Default User" profile to "Default User Temp" $errorcheck = DirMove(@HomeDrive & "\Documents and Settings\" & $default_user_folder, _ @HomeDrive & "\Documents and Settings\Default User Temp", 1) ; Checks for error If $errorcheck = 0 Then ReverseMigrate("Migrate_RenameDefaultUser", $user) EndIf ; Overwrites "Default User" folder name in registry RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList", _ "DefaultUserProfile", "REG_SZ", "Default User") ; Renames user's UCO_SNA profile to "Default User" $errorcheck = DirMove(FileGetLongName($userprofile), @HomeDrive & "\Documents and _ Settings\Default User", 1) ; Checks for error If $errorcheck = 0 Then ReverseMigrate("Migrate_RenameUserProfile", $user) EndIf ; Deletes "ntuser.ini" and "ntuser.dat.log" from new "Default User" profile ; This allows profile to be renamed and still be usable FileDelete(@HomeDrive & "\Documents and Settings\Default User\ntuser.ini") FileDelete(@HomeDrive & "\Documents and Settings\Default User\ntuser.dat.log") ; Disables automatic logon RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", _ "AutoAdminLogon", "REG_SZ", 0) RegDelete("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", _ "DefaultPassword") RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", _ "DefaultUserName", "REG_SZ", $user) RegDelete("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", _ "ForceAutoLogon") ; Adds new UCOK user account to the local Administrators group RunWait("net localgroup Administrators UCOK\" & $user & " /add") ; Modifies profile path for user's UCO_SNA account to use backup profile RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows _ NT\CurrentVersion\ProfileList\" & $sid, "ProfileImagePath", "REG_EXPAND_SZ", _ $newprofilepath) ; Modifies registry entry so that script will run again on next logon RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", _ "Migrate_Profile", "REG_SZ", FileGetShortName(@ScriptFullPath) & " 4 " & $user) ; Logs off so that the user can now log in with their UCOK domain account Shutdown(0) EndFunc Func Cleanup($user) ; Removes generic UCOK user from local Administrators group RunWait("net localgroup Administrators UCOK\" & $ucok_user & " /delete") ; Renames "Default User" to $user_Backup DirMove(@HomeDrive & "\Documents and Settings\Default User", @HomeDrive & "\Documents _ and Settings\" & $user & "_Backup", 1) ; Renames "Default User Temp" to "Default User" DirMove(@HomeDrive & "\Documents and Settings\Default User Temp", @HomeDrive & _ "\Documents and Settings\Default User", 1) ; Removes "Migrate_Profile" registry entry RegDelete("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", _ "Migrate_Profile") ; Displays message informing user that profile migration process is complete MsgBox(64, "Profile Migrated Successfully!", "Your UCO_SNA profile has been _ successfully migrated to the new UCOK domain! All of your settings and preferences _ on this computer should have remained intact. If you have any questions about this _ process, please contact the UCO Technology Support Help Desk at x2255. Thank you _ for your cooperation.") ; Removes user's UCO_SNA account from local Administrators group RunWait("net localgroup Administrators UCO_SNA\" & $user & " /delete") ; Sets RunAs so that programs run after this point will run under different credentials RunAsSet($admin_user, "UCO_SNA", $admin_user_password) ; Runs script to disable user's UCO_SNA account Run("wscript " & FileGetShortName(@ScriptDir) & "\Migrate_Profile_WSH.vbs 4 " & $user) ; Sets RunAs back to the current user RunAsSet() EndFunc Func Error($err, $user) Select Case $err == "NotAdmin" ; Notifies user if user is not in local Administrators group MsgBox(48, "Need Administrative Access!", "The currently logged on user is not an _ administrator on this PC." & $errormsg) Case $err == "WrongOS" ; Notifies user if operating system is not Windows 2000 or XP MsgBox(48, "Wrong OS!", "The operating system installed on this computer is not _ Windows 2000 or Windows XP." & $errormsg) Case $err == "WrongDomain" ; Notifies user if user is not using a UCO_SNA account MsgBox(48, "Wrong Domain!", "You are not currently using a UCO_SNA domain user _ account. Your profile does not need to be migrated." & $errormsg) Case $err == "NotEnoughSpace" ; Notifies user if there is not enough free space to copy profile MsgBox(48, "Not Enough Space!", "Space needed: " & $freespaceneeded & " MB" & _ @CRLF & @CRLF & "Space available: " & $hdfreespace & " MB" & @CRLF & @CRLF & _ "There is not enough free hard disk space to back up your profile." & $errormsg) Case $err == "NoUserAccount" ; Notifies user if UCOK account matching currently logged in account is not found MsgBox(48, "UCOK Account Not Found!", "A user account for """ & $user & """ _ could not be located in the UCOK domain." & $errormsg) Case $err == "Migrate_WrongUser" ; Notifies user if wrong user is logged on during copy profile operation MsgBox(48, "Wrong User!", "The wrong user account is logged on. The user's profile _ will not be copied." & $errormsg) Case $err == "Migrate_RenameDefaultUser" ; Notifies user if default user profile could not be renamed MsgBox(48, "Error Migrating Profile", "An error was encountered during the profile _ migration process (Default User profile could not be renamed)." & $errormsg) Case $err == "Migrate_RenameUserProfile" ; Notifies user if their user profile could not be renamed MsgBox(48, "Error Migrating Profile", "An error was encountered during the profile _ migration process (user profile could not be renamed)." & $errormsg) Case $err == "Migrate_CompareSIDs" ; Notifies user if SIDs pulled from ID1 and ID2 do not match MsgBox(48, "Error Migrating Profile", "An error was encountered during the profile _ migration process (SID could not be retrieved)." & $errormsg) Case $err == "Migrate_VerifySID" ; Notifies user if information read from registry using SID is incorrect MsgBox(48, "Error Migrating Profile", "An error was encountered during the profile _ migration process (SID user name not equal to actual user name)." & $errormsg) EndSelect ; Sends e-mail notification to tech RunWait("cmd /C echo Computer Name: " & @ComputerName & " | " & @ScriptDir & _ "\mailsend -d ucok.edu -smtp 192.206.65.11 -t " & $error_email & " -f " & $user & _ "@ucok.edu -sub ""Profile Migration Error - " & $err & """") ; Logs user off if necessary If StringLeft($err, 8) = "Migrate_" Then Shutdown(0) EndIf ; Exits script, as an error has occurred Exit EndFunc Func CreateFreeSpace() ; Deletes profile temp data in order to decrease profile size RunWait("cmd /C rd /s /q ""%temp%""") RunWait("cmd /C md ""%temp%""") ; Deletes system temp data to free up hard disk space RunWait("cmd /C rd /s /q ""%windir%\Temp""") RunWait("cmd /C md ""%windir%\Temp""") ; Deletes temporary Internet files RunWait("cmd /C rd /s /q ""%userprofile%\Local Settings\Temporary Internet Files""") EndFunc Func CheckProfileSize() ; Calls script to get profile size Run("wscript " & FileGetShortName(@ScriptDir) & "\Migrate_Profile_WSH.vbs 1 " & _ FileGetShortName(@ScriptFullPath) & " " & FileGetShortName(@UserProfileDir)) ; Exits script ; Migrate_Profile_WSH.vbs script will call this script again when finished Exit EndFunc Func VerifySpace($profilesize) ; Gets current partition free space in MB $hdfreespace = DriveSpaceFree(@HomeDrive) ; Sets free space needed based on profile size + 100 MB $freespaceneeded = $profilesize / 1048576 + 100 ; Sets variables to a precision of two decimal places for display $hdfreespace = StringFormat("%.2f", $hdfreespace) $freespaceneeded = StringFormat("%.2f", $freespaceneeded) ; Verifies there is enough free space If ($hdfreespace * 1) < ($freespaceneeded * 1) Then Error("NotEnoughSpace", @UserName) EndIf EndFunc Func CheckForUser() ; Backs up current value for %username% as it will change when doing a RunAs $user = @UserName ; Backs up current value for %userprofile% as it will change when doing a RunAs $userprofile = FileGetShortName(@UserProfileDir) ; Sets RunAs so that programs run after this point will run under different credentials RunAsSet($ucok_user, "UCOK", $ucok_user_password) ; Runs script to determine if the user has a UCOK account $wsh_error = RunWait("wscript " & FileGetShortName(@ScriptDir) & _ "\Migrate_Profile_WSH.vbs 2 " & FileGetShortName(@ScriptFullPath) & " " & $user & " " _ & $userprofile) ; Set RunAs back to current user RunAsSet() ; Displays error if no matching user account was found on the UCOK domain If $wsh_error = 1 Then Error("NoUserAccount", @UserName) EndIf EndFunc Func CopyPrep() ; Adds generic UCOK user to the Administrators group on the PC for profile copy RunWait("net localgroup Administrators UCOK\" & $ucok_user & " /add") ; Configures registry so that generic UCOK user will automatically log on RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", _ "AutoAdminLogon", "REG_SZ", 1) RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", _ "DefaultDomainName", "REG_SZ", "UCOK") RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", _ "DefaultPassword", "REG_SZ", $ucok_user_password) RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", _ "DefaultUserName", "REG_SZ", $ucok_user) RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", _ "ForceAutoLogon", "REG_SZ", 1) ; Creates registry entry so that script will run again on next logon RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", _ "Migrate_Profile", "REG_SZ", FileGetShortName(@ScriptFullPath) & " 3 " & _ FileGetShortName(@UserProfileDir) & " " & @UserName) ; Backs up current value for %username% as it will change when doing a RunAs $user = @UserName ; Sets RunAs so that programs run after this point will run under different credentials RunAsSet($admin_user, "UCOK", $admin_user_password) ; Runs script to enable user's UCOK account RunWait("wscript " & FileGetShortName(@ScriptDir) & "\Migrate_Profile_WSH.vbs 3 " & $user) ; Sets RunAs back to the current user RunAsSet() EndFunc Func ReverseMigrate($err, $user) ; Disables automatic logon RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", _ "AutoAdminLogon", "REG_SZ", 0) RegDelete("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", _ "DefaultPassword") RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", _ "DefaultUserName", "REG_SZ", $user) RegDelete("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", _ "ForceAutoLogon") ; Deletes "Migrate_Profile" registry entry RegDelete("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", _ "Migrate_Profile") If $err = "Migrate_RenameUserProfile" Then ; Renames "Default User Temp" profile to "Default User" DirMove(@HomeDrive & "\Documents and Settings\Default User Temp", @HomeDrive & _ "\Documents and Settings\Default User", 1) EndIf Error($err, $user) EndFunc Func GetSid($user) ; Outputs SID information to log file in %temp% RunWait("cmd /C """ & @ScriptDir & "\getsid"" \\id1 " & $user & " \\id2 " & $user & " > _ %temp%\getsid.log") ; Opens log file for reading $getsid_log = FileOpen(@TempDir & "\getsid.log", 0) ; Reads lines 2 and 3 into variables $getsid_line2 = FileReadLine($getsid_log, 2) $getsid_line3 = FileReadLine($getsid_log, 3) ; Closes and deletes file, as it is no longer needed FileClose($getsid_log) FileDelete(@TempDir & "\getsid.log") ; Extracts SID from line 2 $sid_line2 = StringTrimLeft($getsid_line2, StringLen($user) + 32) ; Extracts SID from line 3 $sid_line3 = StringTrimLeft($getsid_line3, StringLen($user) + 32) ; Compares extracted SIDs to verify they are identical If $sid_line2 <> $sid_line3 Then ReverseMigrate("Migrate_CompareSIDs", $user) EndIf ; Returns SID Return $sid_line2 EndFunc Func GetProfilePath($sid, $user) ; Reads user's profile path from registry using SID $profilepath = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows _ NT\CurrentVersion\ProfileList\" & $sid, "ProfileImagePath") ; Initializes $profilefolder variable to prepare for loop $profilefolder = $profilepath ; Loops until all extra information is removed from profile path ; End result is user's profile folder name While 1 $backslash = StringInStr($profilefolder, "\") If $backslash <> 0 Then $profilefolder = StringTrimLeft($profilefolder, $backslash) Else ExitLoop EndIf WEnd ; Extracts user name from profile folder name $user_check = StringLeft($profilefolder, StringLen($user)) ; Compares extracted user name with known user name to verify they are identical If $user <> $user_check Then ReverseMigrate("Migrate_VerifySID", $user) EndIf ; Extracts current profile path without profile folder name $profilepath = StringTrimRight($profilepath, StringLen($profilefolder)) ; Appends backup profile folder name to profile path $newprofilepath = $profilepath & $user & "_Backup" ; Returns new profile path Return $newprofilepath EndFuncHere is the .vbs file that is called for some of the advanced functions:expandcollapse popup' ---------------------------------------------------------------------------------------- ' ' Script Name: Migrate_Profile_WSH.vbs ' ' Author: Greg Mackey <gmackey@ucok.edu> ' ' Supported OS: Windows 2000/XP ' ' Other Requirements: Windows Script 5.6 ' ' Script Function: Contains advanced subroutines that the main AutoIt v3 script does ' not support. ' ' Changelog: (See "readme.txt" for changelog) ' ' ---------------------------------------------------------------------------------------- ' Stops the script if no arguments are specified If WScript.Arguments.Count=0 Then WScript.Quit() End If ' Selects which subroutine to call based on the option specified (1-3) Select Case WScript.Arguments(0) Case "1" Call CheckProfileSize(WScript.Arguments(1), WScript.Arguments(2)) Case "2" Call CheckForUser(WScript.Arguments(1), WScript.Arguments(2), WScript.Arguments(3)) Case "3" Call EnableUserAccount(WScript.Arguments(1)) Case "4" Call DisableUserAccount(WScript.Arguments(1)) End Select ' Determines size of user's profile and pass back to main script Sub CheckProfileSize(strScriptPath, strUserProfile) ' Declares variables Dim objFSO, objFolder, objShell ' Gets size of user's profile Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFolder = objFSO.GetFolder(strUserProfile) ' Calls main script and passes profile size to it Set objShell = WScript.CreateObject("WScript.Shell") objShell.Exec(strScriptPath & " 2 " & objFolder.size) ' Empties variables Set objShell = nothing Set objFolder = nothing Set objFSO = nothing End Sub ' Determines whether user has a UCOK account based on their UCO_SNA user name Sub CheckForUser(strScriptPath, strUserName, strUserProfile) ' Declares variables Dim objConnection, objCommand, objRecordSet ' Initializes Active Directory connection Set objConnection = CreateObject("ADODB.Connection") objConnection.Open "Provider=ADsDSOObject;" ' Initializes Active Directory command object Set objCommand = CreateObject("ADODB.Command") objCommand.ActiveConnection = objConnection ' Defines Active Directory command that will be executed objCommand.CommandText = _ "<LDAP://dc=ucok,dc=edu>;(&(objectCategory=User)" & _ "(samAccountName=" & strUserName & "));samAccountName;subtree" ' Executes defined Active Directory command ' Attempts to find user name in Active Directory structure ' Records any matches in a database recordset Set objRecordSet = objCommand.Execute ' Initializes shell object for next operation Set objShell = WScript.CreateObject("WScript.Shell") ' If no matches were found in recordset, error code is sent back to main script ' If a match was found, main script is called in order to continue processing If objRecordset.RecordCount = 0 Then ' Closes Active Directory connection objConnection.Close ' Empties variables Set objRecordSet = nothing Set objCommand = nothing Set objConnection = nothing ' Returns error code "1" (failure) WScript.Quit(1) Else ' Closes Active Directory connection objConnection.Close ' Empties variables Set objRecordSet = nothing Set objCommand = nothing Set objConnection = nothing ' Returns error code "0" (success) WScript.Quit(0) End If End Sub ' Enables user's UCOK account to allow them to log in and finish the process Sub EnableUserAccount(strUserName) ' Declares variables Dim objUser ' Clears "Disabled" check box on user's UCOK account, if it is checked Set objUser = GetObject("WinNT://UCOK/" & strUserName & ",user") objUser.AccountDisabled = False objUser.SetInfo End Sub ' Disables user's UCO_SNA account once the migration process is complete Sub DisableUserAccount(strUserName) ' Declares variables Dim objUser ' Sets user's UCO_SNA account to "Disabled" Set objUser = GetObject("WinNT://UCO_SNA/" & strUserName & ",user") objUser.AccountDisabled = True objUser.SetInfo End SubHere is the "parameters.txt" file:- The error message below is the generic part displayed to users when an error occurs during the script. - This error message can be customized by each tech support area. - The complete message must remain on LINE 6 of this text file. ERROR MESSAGE: Please call the UCO Technology Support Help Desk at x2255 to report this problem so that it can be corrected. No changes will be made to your system or your account until the Help Desk is contacted and this problem is corrected. Thank you for your cooperation. - The e-mail address below receives notifications of any errors encountered in the script. - This e-mail address can be customized by each tech support area. - The e-mail address must remain on LINE 15 of this text file. E-MAIL ADDRESS: support@ucok.eduThe scripts have been tested thoroughly and all known bugs have been removed. If you want to send me an e-mail or anything, just send it to gmackey@ucok.edu. I hope this post isn't too large! Greg MackeyTech Support Spec III / Lab Supervisor - ITUniversity of Central Oklahoma Edited March 12, 2010 by Valik
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