Posted in : Citrix, Virtual Apps and Desktops By Adam Clark

2 years ago

Recently, I have been involved in some larger XenApp projects where one of the objects have been to migrate home directories when users change environment. People tend to lock themselves to the idea that IT must help migrate home directory when the user is given access to the new environment. A better way to approach this is to publish a script to the start menu and inform users to run the script when first logging in to the new environment. In one of the projects it were a bit more complicated because the home directory structure was different from the structure in the new XenApp environment (see below).
 
Old structure

  • Links
  • Favorites
  • Downloads
  • Documents
    • My Music
    • My Videos
    • My Pictures
  • Desktop
  • Contacts
  • AppData

 
New structure

  • Downloads
  • Documents
  • Pictures
  • Music
  • Videos
  • Desktop

 
To solve this we had to create a PowerShell script with a bit more logic. Basically what we do is the following;

  1. Copy everything from old home directory to the new home directory, except the excluded folders and files
  2. Copy ”\Documents\Music” to ”\Music”
  3. Copy ”\Documents\Videos” to ”\Videos”
  4. Copy ”\Documents\Pictures” to ”\Pictures”
  5. Copy ”\Favorites” to ”\%USERPROFILE%\Favorites” (It’s bad practice to redirect Favorites. Read more here)
  6. Copy necessary items from ”\AppData\~” to ”\%USERPROFILE%\AppData\~” (We use Citrix Profile Management instead of redirecting AppData to the home share. Redirecting AppData to the home share is also bad practice. Same reason as why it’s bad practice to redirect Favorites.)

 

<#
    .NOTES
        Name: CTX-VDA-PROD-WS16-A-Copy-HomeDirectory.ps1
        Author: Måns Hurtigh, Xenit AB
        Date Created: 2018-10-15
        Version History:
            2018-10-15
            -Initial Creation
#>
[cmdletbinding()]
Param(
    [string]$src = '\\server\homecatalogs\' + $env:USERNAME,
    [string]$dst = '\\newserver\Home\' + $env:USERNAME,
    [array]$exclusionList = @('\Appdata','\Contacts','\Documents\My Music','\Documents\My Pictures','\Documents\My Videos','\Favorites','\Links','\WINDOWS','\*\$RECYCLE.BIN','\*\desktop.ini')
)
Begin {
    [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
    Function Copy-SpecialFolders {
    [cmdletbinding()]
    Param(
        [string]$src,
        [string]$dst,
        [string]$OldStruct,
        [string]$NewStruct,
        [string[]]$Exclude
    )
        Get-ChildItem -LiteralPath "$src$OldStruct" -Force -Recurse -Exclude $Exclude | ForEach-Object{
            $destination = "$dst$($_.FullName.Replace($src,'').Replace($OldStruct,$NewStruct))"
            If(Test-Path $_.FullName -Type Leaf){
                $destination = ($destination.Split('\')[0..($destination.Split('\').Count-2)]) -join '\'
                Copy-Item -LiteralPath $_.FullName -Destination $destination -Force
            }
            Else{
                New-Item -Path $destination -ItemType Container -Force
            }
        }
    }
}
Process {
    if (Test-Path $src -PathType Container) {
        $MSGBoxTitle = "Copy the entire home directory from the old environment"
        $MSGBoxText	= "Press Yes to copy the home directory from the old environment or press No to cancel"
        $PopupObject = [System.Windows.Forms.MessageBox]::Show($MSGBoxText, $MSGBoxTitle , 4)
        if ($PopupObject -eq "YES") {
	        #Copy Root files
            Get-childItem $src -File | ForEach-Object{Copy-Item $_.FullName $dst -Force}
            #Copy rest of folders with exclusionlist
            $ToCopy = Get-ChildItem $src -Force -Recurse | ForEach-Object{
                $thisFolder = $_.FullName
                If(-not($exclusionList | Where-Object{$thisFolder -like "$($src)$($_)*"})){
                    $thisFolder
                }
            }
            $ToCopy | ForEach-Object{
                $destination = "$dst$($_.Replace($src,''))"
                If(Test-Path $_ -Type Leaf){
                    $destination = ($destination.Split('\')[0..($destination.Split('\').Count-2)]) -join '\'
                    Copy-Item -LiteralPath $_ -Destination $destination -Force
                }
                Else{
                    New-Item -Path $destination -ItemType Container -Force
                }
            }
            Copy-SpecialFolders -src $src -dst $dst -OldStruct '\Documents\My Music' -NewStruct '\Music' -Exclude '*$RECYCLE.BIN','*desktop.ini'
            Copy-SpecialFolders -src $src -dst $dst -OldStruct '\Documents\My Videos' -NewStruct '\Videos' -Exclude '*$RECYCLE.BIN','*desktop.ini'
            Copy-SpecialFolders -src $src -dst $dst -OldStruct '\Documents\My Pictures' -NewStruct '\Pictures' -Exclude '*$RECYCLE.BIN','*desktop.ini'
            Copy-Item -LiteralPath "$src\Favorites" -Destination $env:USERPROFILE -Recurse -Force
            New-Item -ItemType directory -Path "$env:APPDATA\Microsoft\Signatures"
            Get-ChildItem -LiteralPath "$src\AppData\Roaming\Microsoft\Signaturer" -Force -Recurse | ForEach-Object{
                $destination = "$($_.FullName.Replace($src,$env:USERPROFILE).Replace('Signaturer','Signatures'))"
                If(Test-Path $_.FullName -Type Leaf){
                    $destination = ($destination.Split('\')[0..($destination.Split('\').Count-2)]) -join '\'
                    Copy-Item -LiteralPath $_.FullName -Destination $destination -Force
                }
                Else{
                    New-Item -Path $destination -ItemType Container -Force
                }
            }
            $MSGBoxTitle = "Finished"
            $MSGBoxText	= "Your old home directory has now been copied."
            $PopupObject = [System.Windows.Forms.MessageBox]::Show($MSGBoxText, $MSGBoxTitle , 0)
        }
    }
    else {
        $MSGBoxTitle = "Could not find your old home directory"
        $MSGBoxText	= "Your old home directory could not be found. Please contact the IT department."
        $PopupObject = [System.Windows.Forms.MessageBox]::Show($MSGBoxText, $MSGBoxTitle , 0)
    }
}
End {
}

 
The end result looks like this;.
User runs ”Copy Home Directory” from Start Menu as instructed
Copy Home Directory
A box pops up
Popup - Copy the entire home directory from the old environment
Another box pops up when the script is finished copying the old home directory
Popup - Finished

Tags :

Add comment

Your comment will be revised by the site if needed.