public/Migrate-Homes.ps1

<#
Elliott's User Data Migration Tool
 
Run this script on a new DC that you have copied the old user home folders on to
Point $OldHomeDirectory to root folder of old user homes eg "D:\OLD-SERVER-DATA\USER-HOMES\"
Point $NewHomeDirectory to root folder of new user homes, eg "D:\User Data\Home\Office"
 
Prerequisites / Things to be aware of
    - You need to create all users on the new server first, this script looks for their home folders and only copies matching ones from the old directory
    - You MUST use the same username format as the old server!
    - Starting in W10 user libraries dropped the "My" from the start (eg "My Documents" became just "Documents") this script looks for them and removes the "My"
 
#>

 
Function Migrate-Homes {

 
 Param(

    [Parameter(Mandatory=$true,Position=0)]
    [string]$OldHomeDirectory,

    [Parameter(Mandatory=$true,Position=0)]
    [string]$NewHomeDirectory,

    [Parameter(Mandatory=$true,Position=0)]
    [string]$LogDirectory

) #end param

# Check directories exist and if they do attempt to convert them to their full names
if ((Test-Path $OldHomeDirectory) -eq $False) {
    Write-Warning "Old home directory not found" -WarningAction Stop
    }else{
    $OldHomeDirectory = (Get-Item $OldHomeDirectory).fullname
    }
Write-Output "The old home directory has been set to $OldHomeDirectory"

if ((Test-Path $NewHomeDirectory) -eq $False) {
    Write-Warning "New home directory not found" -WarningAction Stop
    }else{
    $NewHomeDirectory = (Get-Item $NewHomeDirectory).fullname
    }
Write-Output "The new home directory has been set to $NewHomeDirectory"

# Create a migration logs directory if it doesnt already exist
$LogPath = "$LogDirectory\Data Migration Logs"
if (-not(test-path $LogPath)) {
    new-item -Path $LogPath -ItemType Directory
    }
Write-Output "The log path has been set to $((Get-Item $LogPath).fullname)"

$Confirm = Read-Host "Please confirm these paths are correct (Y/N)"

If (!($Confirm -eq "Y")) {break}

#Remove all desktop.ini & $RECYCLE.BIN files in old home dirs
Write-Host "Removing unecessary files from user homes"
Sleep 3
Get-ChildItem $OldHomeDirectory -Recurse -Attributes h,s -Include desktop.ini, '$RECYCLE.BIN' | Remove-Item -Force -Recurse -Verbose
Get-ChildItem $OldHomeDirectory -Recurse -Include '$RECYCLE.BIN' | Remove-Item -Force -Recurse -Verbose

# Get all the new user folders in the specified directory
$NewUserHomes = Get-ChildItem -Path $NewHomeDirectory | Where-Object { $_.PSIsContainer }

# Loop through each folder and copy everything across
foreach ($Folder in $NewUserHomes){

    #Generate username based on new home folder
    $Username = $Folder.Name
    #Get fullname of folder so Robocopy doesnt get grumpy later on
    $NewUserHome = $Folder.Fullname
    #Use only the new usernames to generate a path to the old user folder to ensure you dont copy data of users that no longer exist
    $OldUserHome = "$OldHomeDirectory\$Username"
    #Create the log file
    $LogFile = "$LogPath\$Username.txt"

    # If to test that a user in the old folder has actually been created on the new server
    if (Test-Path $OldUserHome){
        
        # Copy everything in to the new user folder
        Robocopy $OldUserHome $NewUserHome /E /MOVE /LOG+:$LogFile

        #Rename any old "My xxx" folders from Windows 7 and earlier to the new Windows 10 format

        if (Test-Path "$NewUserHome\My Documents"){
            Rename-Item -Path "$NewUserHome\My Documents" -NewName Documents -Force
            }

        if (Test-Path "$NewUserHome\My Pictures"){
            Rename-Item -Path "$NewUserHome\My Pictures" -NewName Pictures -Force
            }

        if (Test-Path "$NewUserHome\My Videos"){
            Rename-Item -Path "$NewUserHome\My Videos" -NewName Videos -Force
            }

        if (Test-Path "$NewUserHome\My Video"){
            Rename-Item -Path "$NewUserHome\My Video" -NewName Videos -Force
            }

        if (Test-Path "$NewUserHome\My Music"){
            Rename-Item -Path "$NewUserHome\My Music" -NewName Music -Force
            }
            
        if (Test-Path "$NewUserHome\Favorites"){
            Rename-Item -Path "$NewUserHome\Favorites" -NewName Favourites -Force
            }


            # Create a documents folder if one didnt exist (if root of home folder was treated as the documents folder)
        if (-not(Test-Path "$NewUserHome\Documents")){
            New-Item -Path $NewUserHome -Name Documents -ItemType Directory -Force
            }

        #Move everything thats not in Favorites/Pictures/Music/Videos/Desktop in to the Documents Folder also include "My..." Folders incase the rename operation above failed for whatever reason

        $RC_ParameterStrings = @(
        $NewUserHome
        "$NewUserHome\Documents"
        '/MOVE'
        '/E'
        "/LOG+:$LogFile"
        '/XD'
        'Favorites'
        'Favourites'
        'Documents'
        'Pictures'
        'Videos'
        'Desktop'
        'Music'
        'My Documents'
        'My Pictures'
        'My Music'
        'My Videos'
        )

        Robocopy $RC_ParameterStrings

        Write-Host "$Username's data has been successfully migrated!" -ForegroundColor Cyan

    }else{
        Write-Output "$Username was in the NEW folder but did not exist in the OLD folder!" | Out-File -FilePath $LogPath\_Failed_Users.txt
        }
#End Loop
}

}