18 August 2014

Transferring data between user profiles

Sometimes when you use USMT, it fails for one reason or another. This script is here to transfer user files from one profile to another. It was written so that in the event USMT fails, there is still a means to automate the transfer of user data.

The first step is to login as the end user, or have then login, on the new machine. They can log right back out. This is to create the user profile on the new PC. Once the user has done this, you can now proceed with running the script. It uses robocopy to move the files over. I have also incorporated using PSEXEC to initiate the robocopy command so that the data goes directly from the source to the destination, with no intermediary to slow down the transfer, especially if you are transferring data in a remote office. 

One more feature I have included in the script is the capability of transferring data from an old, renamed profile to a newly created profile on the same machine. 

Before you run this script, you will need to install PSEXEC at some network location for the script to use and also go through and select what you want excluded in the transfer. I have also made the transfer create a log file, which will also need to be customized to your environment. 

You can download the script from here.

   Author: Mick Pletcher  
   Date: 04 March 2014  
   Synopsis: This script will robocopy specific user data from one profile to another on  
                   the same machine, or to a new machine. It will require user input in the following  
                 1) Have the user logout  
                 2) Rename the user profile to <profile>.old  
                 3) Have the user log back in  
                 1) Define Global Memory  
                 2) Get the relative path  
                 3) User input  
                      a) User profile to copy  
                     b) Is the profile to be copied to a new machine  
                     c) If yes, what is the computer name of the new machine  
                 4) Get the OS version of the source machine  
                 5) If copying to a new machine, get the OS version of destination machine  
 #Define Global Variables  
 Set-Variable -Name AdminPassword -Scope Global -Force  
 Set-Variable -Name AdminUsername -Scope Global -Force  
 Set-Variable -Name DestinationComputer -Scope Global -Force  
 Set-Variable -Name DestinationProfile -Scope Global -Force  
 Set-Variable -Name RelativePath -Scope Global -Force  
 Set-Variable -Name SourceComputer -Scope Global -Force  
 Set-Variable -Name SourceProfile -Scope Global -Force  
 Function GetRelativePath {   
      $Global:RelativePath = (split-path $SCRIPT:MyInvocation.MyCommand.Path -parent)+"\"   
 Function GetUserInput {  
      #Define Local Memory  
      Set-Variable -Name Message -Scope Local -Force  
      Set-Variable -Name No -Scope Local -Force  
      Set-Variable -Name Options -Scope Local -Force  
      Set-Variable -Name Result -Scope Local -Force  
      Set-Variable -Name Title -Scope Local -Force  
      Set-Variable -Name Username -Scope Local -Force  
      Set-Variable -Name Yes -Scope Local -Force  
      $Username = Read-Host "Enter the username"  
      $Global:SourceComputer = Read-Host "Enter the computer name of the source system"  
      $Title = ""  
      $message = "Is the profile to be copied to a different machine?"  
      $Yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "Copy files to profile on different machine"  
      $No = New-Object System.Management.Automation.Host.ChoiceDescription "&No", "Copy files to new profile on same machine"  
      $Options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)  
      $Result = $host.ui.PromptForChoice($title, $message, $options, 0)   
      If ($Result -eq 1) {  
           $Global:DestinationComputer = $Global:SourceComputer  
           $Global:SourceProfile = Read-Host "Enter renamed profile name"  
           $Global:SourceProfile = "\\"+$Global:SourceComputer+"\c$\users\"+$Global:SourceProfile  
           $Global:DestinationProfile = "\\"+$Global:DestinationComputer+"\c$\users\"+$Username  
      } else {  
           $Global:DestinationComputer = Read-Host "Enter the computer name of the new machine"  
           #$Global:SourceProfile = $Env:systemdrive+"\users\"+$Username  
           $Global:SourceProfile = $Username  
           $Global:DestinationProfile = "\\"+$Global:DestinationComputer+"\c$\users\"+$Username  
      $Global:AdminUsername = Read-Host "Enter administrator username"  
      $Global:AdminPassword = Read-Host -AsSecureString "Enter administrator account password"  
      $Global:AdminPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Global:AdminPassword))  
      $Global:AdminUsername = "[Domain]\"+$Global:AdminUsername  
      #Cleanup Local Memory  
      Remove-Variable -Name Message -Scope Local -Force  
      Remove-Variable -Name No -Scope Local -Force  
      Remove-Variable -Name Options -Scope Local -Force  
      Remove-Variable -Name Result -Scope Local -Force  
      Remove-Variable -Name Title -Scope Local -Force  
      Remove-Variable -Name Username -Scope Local -Force  
      Remove-Variable -Name Yes -Scope Local -Force  
 Function RoboCopyFiles {  
      #Define Local Memory  
      Set-Variable -Name ErrCode -Scope Local -Force  
      Set-Variable -Name ExcludeDir -Scope Local -Force  
      Set-Variable -Name ExcludeFiles -Scope Local -Force  
      Set-Variable -Name EXE -Scope Local -Force  
      Set-Variable -Name Logs -Scope Local -Force  
      Set-Variable -Name Parameters -Scope Local -Force  
      Set-Variable -Name RemoteExec -Scope Local -Force  
      Set-Variable -Name Robocopy -Scope Local -Force  
      Set-Variable -Name Switches -Scope Local -Force  
      $EXE = "\\BNASANIS01\SupportServices\Tools\PSTools\PsExec.exe"  
      $RemoteExec = "\\"+$Global:SourceComputer+[char]32+"-accepteula -u $Global:AdminUsername -p $Global:AdminPassword"+[char]32  
      $Switches = [char]32+"/e /eta /r:1 /w:0"  
      $ExcludeDir = [char]32+"/xd AppData Application* Downloads LocalService *Games* NetworkService *Links* *temp *TEMPOR~1 *cache Local*"  
      $ExcludeFiles = [char]32+"/xf ntuser.* *.exd *.nk2 *.srs extend.dat *cache* *.oab index.* {* *.ost UsrClass.* SharePoint*.pst history* *tmp*"  
      $Logs = [char]32+"/log:"+$Env:windir+"\waller\Logs\ApplicationLogs\ProfileCopy.log"  
      $Parameters = $Switches+$ExcludeDir+$ExcludeFiles+$Logs  
      $Arguments = $RemoteExec+$Env:windir+"\system32\robocopy.exe"+[char]32+$Env:systemdrive+"\users\"+$Global:SourceProfile+[char]32+$Global:DestinationProfile+$Parameters  
      $ErrCode = (Start-Process -FilePath $EXE -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      #Cleanup Local Memory  
      Remove-Variable -Name ErrCode -Scope Local -Force  
      Remove-Variable -Name ExcludeDir -Scope Local -Force  
      Remove-Variable -Name ExcludeFiles -Scope Local -Force  
      Remove-Variable -Name EXE -Scope Local -Force  
      Remove-Variable -Name Logs -Scope Local -Force  
      Remove-Variable -Name Parameters -Scope Local -Force  
      Remove-Variable -Name RemoteExec -Scope Local -Force  
      Remove-Variable -Name Robocopy -Scope Local -Force  
      Remove-Variable -Name Switches -Scope Local -Force  
 Function CopyFiles ($FileSource,$FileDest,$FileFilter) {  
      $Dest = $FileDest  
      $Files = Get-ChildItem $FileSource -Filter $FileFilter  
      If ($Files.Count -eq $null) {  
           Write-Host "Copy "$Files.Name"....." -NoNewline  
           Copy-Item $Files.FullName -Destination $Dest -Force  
           $Test = $Dest + "\"+$Files.Name  
           If (Test-Path $Test) {  
                Write-Host "Success" -ForegroundColor Yellow  
           } else {  
                Write-Host "Failed" -ForegroundColor Red  
      } else {  
           For ($i = 0; $i -lt $Files.Count; $i++) {  
                $File = $Files[$i].FullName  
                Write-Host "Copy"$Files[$i].Name"....." -NoNewline  
                Copy-Item $File -Destination $Dest -Force  
                $Test = $Dest + "\"+$Files[$i].Name  
                If (Test-Path $Test) {  
                     Write-Host "Success" -ForegroundColor Yellow  
                } else {  
                     Write-Host "Failed" -ForegroundColor Red  
 #Copy Outlook Signatures  
 $TempSource = "\\"+$SourceComputer+"\c$\users\"+$SourceProfile+"\AppData\Roaming\Microsoft\Signatures"  
 $TempDestination = "\\"+$DestinationComputer+"\c$\users\"+$DestinationProfile+"\AppData\Roaming\Microsoft\Signatures"  
 CopyFiles $TempSource $TempDestination "*.*"  


Post a Comment