Mar 052022
 

Everyone already knows the famous script from David Ott to migrate Windows Profiles (local) to FSLogix profiles containers. With some modifications the script would work well to convert Citrix UPM profiles to FSLogix.

There is already a good article posted on this website for those who want to use the original script from David Ott:
FSLogix Local Profiles Migration Script

The following script is revamped version, working exclusively with Citrix UPM profiles, and is designed to be a out-of-the-box / turnkey solution to migrate Citrix UPM profiles to FSLogix. All you have to do is enter the user(s) SamAccountName in a text file, and run the script!

The script is meant to be run directly on the file server hosting the FSLogix profiles, as it is still using DiskPart to format the disk, so you cannot run it from the network or remotely – you cannot run DiskPart with network paths! Or if you really want to run it from a different server, it is possible, but then you need to add a Robocopy command at the end to push the profile container to your FSLogix network share. The script is designed to make sure that all user permissions are set correctly.

So this is pretty much it.. Enter the user(s) names in a text file named “fslogixusers.txt” (just update the path to the text file in the script) and run the script!

You need to update the following variables to meet your environment setup:

$users: The path to the text file containing the users (SamAccountName)
$FslogixPath: The path to your FSLogix containers folder, where the converted profiles will be stored.
$UpmPath: The path to your Citrix UPM profiles. Can be a network path.
$UpmProfile: This is to adjust your UPM profile directory structure. By default it is set to the username. If you need to change it for example to Domain\Username then change it there (keep $sam for the username).
$FslogixProfile: Same as above, by default only the $sid is used for the FSLogix container folder. But the script will use the structure Username_SID. You can change this in your FSLogix configuration (GPO) or change this variable.
$VhdMountDir: This should not need to be changed. This is where the profile container is “mounted” on the file system for the profile copy.
$vhd: This is the actual profile container name and format. If you want to switch to VHD instead of VHDX, change it there.

Important Note: The script will use the FSLogix tool “Frx.exe” to create the profile disk. The script expect to find the tool in its default location on the server (“C:\Program Files\FSLogix\Apps\Frx.exe”).
You just need to copy the executable file from one of your server on which FSLogix is installed (Citrix VDA).

Pleas leave a comment if anything is missing.

The Script:

Import-Module ActiveDirectory

#Get users list
$users = Get-Content C:\Scripts\fslogixusers.txt

Foreach ($user in $users) {

#Variables definition - pleae note that the samaccountname must be in lowercase!
$sam = $user
$sid = Get-Aduser $sam
$sid = $sid.SID
$FslogixPath = "Q:\FSLogixProfiles"
$UpmPath = "Q:\UPMProfiles"
$UpmProfile = $UpmPath + "\" + $sam
$FslogixProfile = $FslogixPath + "\" + $sam + "_" + $sid
$VhdMountDir = $FslogixProfile + "\Mount"
$vhd = $FslogixProfile + "\Profile_" + $sam + ".VHDX"

#Create the profile folder and mount directory
New-Item -Path $FslogixProfile -ItemType Directory
New-Item -Path $VhdMountDir -ItemType Directory

#Create VHDX
$FrxParams = 'create-vhd -filename="'  + $vhd + '"' + ' -size-mbs=30720 -dynamic=1'
Start-Process -Wait -Filepath "C:\Program Files\FSLogix\Apps\Frx.exe" -ArgumentList $FrxParams

#Diskpart Assign/Mount
$diskpart1 = "select vdisk file=`"$vhd`"`r`nattach vdisk`r`nselect partition 1`r`nassign mount=`"$VhdMountDir`""
$diskpart1 | diskpart

#Set Permissions
$ProfileFolder = $VhdMountDir + "\Profile"
New-Item -Path $ProfileFolder -ItemType Directory
$setinheritance = $ProfileFolder + " /inheritance:d"
Start-Process -Wait icacls -ArgumentList $setinheritance
$setowner = $ProfileFolder + " /setowner $env:userdomain\$sam"
Start-Process -Wait icacls -ArgumentList $setowner
$setpermission1 = $ProfileFolder + " /grant $env:userdomain\$sam" + ":(OI)(CI)F"
Start-Process -Wait icacls -ArgumentList $setpermission1
$setpermission2 = $ProfileFolder + " /grant Administrators" + ":(OI)(CI)F"
Start-Process -Wait icacls -ArgumentList $setpermission2

#Robocopy
$CopyParams = '/e /copyall "' + $UpmProfile + '\UPM_Profile" "' + $VhdMountDir + '\Profile"'
Start-Process -Wait -Filepath "C:\Windows\System32\Robocopy.exe" -ArgumentList $CopyParams

#ProfileData.reg
$FSLFolder = $VhdMountDir + "\Profile\AppData\Local\FSLogix"
$RegfileOutput = $FSLFolder + "\ProfileData.reg"
New-Item -Path $FSLFolder -ItemType Directory

$RegText = "Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$sid]
`"ProfileImagePath`"=`"C:\\Users\\$sam`"
`"FSL_OriginalProfileImagePath`"=`"C:\\Users\\$sam`"
`"Flags`"=dword:00000000
`"State`"=dword:00000000
`"ProfileLoadTimeLow`"=dword:00000000
`"ProfileLoadTimeHigh`"=dword:00000000
`"RefCount`"=dword:00000000
`"RunLogonScriptSync`"=dword:00000000
"
$RegText | Out-File $RegfileOutput -Encoding ascii

#Diskpart dismount and remove VHD Mount Dir
$diskpart2 = "select vdisk file=`"$vhd`"`r`ndetach vdisk"
$diskpart2 | diskpart
Remove-Item -Path $VhdMountDir -Force

#Set ownsership/permissions for VHDX File
$setowner = $vhd + " /setowner $env:userdomain\$sam"
Start-Process -Wait icacls -ArgumentList $setowner
$setpermission1 = $vhd + " /grant $env:userdomain\$sam" + ":(OI)(CI)F"
Start-Process -Wait icacls -ArgumentList $setpermission1
$setpermission2 = $vhd + " /grant Administrators" + ":(OI)(CI)F"
Start-Process -Wait icacls -ArgumentList $setpermission2

#Set ownsership/permissions for the FSLogix profile folder
$setowner = $FslogixProfile + " /setowner $env:userdomain\$sam"
Start-Process -Wait icacls -ArgumentList $setowner
$setpermission1 = $FslogixProfile + " /grant $env:userdomain\$sam" + ":(OI)(CI)F"
Start-Process -Wait icacls -ArgumentList $setpermission1
$setpermission2 = $FslogixProfile + " /grant Administrators" + ":(OI)(CI)F"
Start-Process -Wait icacls -ArgumentList $setpermission2

#On-screen end notification
write-host "End of Script"
}

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)

This site uses Akismet to reduce spam. Learn how your comment data is processed.