We had a requirement to migrated 8000+ Citrix User UPM profiles across globe to FSLogix Profiles (.VHDX) as customer wanted to move from Citrix to AVD. This was a very challenging requirement due to new experience

#Below Script used to convert UPM Profile Path to FSlogix profile path by retaining NTFS Permissions
# Fslogix Root profile path
$newprofilepath = "\\<StorageAccountName>.file.core.windows.net\<ShareName>" 
# UPM Root profile path
$oldprofilepath = "<Profile Share Path>" # Provide UPM Profile Path
$newusers = @()
ForEach ($user in(gc "C:\temp\users.txt")) {
$path = $oldprofilepath + $user
if(Test-Path -Path $path){
$newusers += $user    
}
else{
Write-Output "$user does not exist"
}
}
ForEach ($user in $newusers) {
# Subfolder 1 - First Path to UPM_Profile Folder in UPM Profiles
$subfolder1 = ""
# Subfolder 2 - First Path to UPM_Profile Folder in UPM Profiles
#$subfolder2 =
$sam = "$user"
Start-Sleep -s 10
######################################################
$iniownr = (Get-Acl (Get-ChildItem "C:\temp\$sam" -force -Recurse ).FullName).Owner
takeown /f $sam /r /d y
Start-Sleep -s 10
icacls "C:\Temp\$sam" /grant zs_wvd_prod:f /q /c /t
#####################################################
Start-Sleep -s 10
#########################################################################################
# Do not edit here
#########################################################################################
$old = $oldprofilepath + $sam + $subfolder1;
$sid = (New-Object System.Security.Principal.NTAccount($sam)).translate([System.Security.Principal.SecurityIdentifier]).Value
$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
"
$nfolder = join-path $newprofilepath ($sid+"_"+$sam)
if (!(test-path $nfolder)) {New-Item -Path $nfolder -ItemType directory | Out-Null}
#& icacls $nfolder /setowner "$env:userdomain\$sam" /T /C
#& icacls $nfolder /grant $env:userdomain\$sam`:`(OI`)`(CI`)F /T
& icacls $nfolder /grant $sam`:`(OI`)`(CI`)F /T
$vhd = Join-Path $nfolder ("Profile_"+$sam+".vhdx")
$script1 = "create vdisk file=`"$vhd`" maximum 30720 type=expandable"
$script2 = "sel vdisk file=`"$vhd`"`r`nattach vdisk"
$script3 = "sel vdisk file=`"$vhd`"`r`ncreate part prim`r`nselect part 1`r`nformat fs=ntfs quick"
$script4 = "sel vdisk file=`"$vhd`"`r`nsel part 1`r`nassign letter=T"
$script5 = "sel vdisk file`"$vhd`"`r`ndetach vdisk"
$script6 = "sel vdisk file=`"$vhd`"`r`nattach vdisk readonly`"`r`ncompact vdisk"
if (!(test-path $vhd)) {
$script1 | diskpart
$script2 | diskpart
Start-Sleep -s 5
$script3 | diskpart
$script4 | diskpart
& label T: Profile-$sam
New-Item -Path T:\Profile -ItemType directory | Out-Null
start-process icacls "T:\Profile /setowner SYSTEM"
Start-Process icacls -ArgumentList "T:\Profile /inheritance:r"
$cmd1 = "T:\Profile /grant $env:userdomain\$sam`:`(OI`)`(CI`)F"
Start-Process icacls -ArgumentList "T:\Profile /grant SYSTEM`:`(OI`)`(CI`)F"
Start-Process icacls -ArgumentList "T:\Profile /grant Administrators`:`(OI`)`(CI`)F"
Start-Process icacls -ArgumentList $cmd1
} else {
$script2 | diskpart
Start-Sleep -s 5
$script4 | diskpart
}
"Copying $old to $vhd"
& robocopy $old T:\Profile /MIR /r:0 | Out-Null
if (!(Test-Path "T:\Profile\AppData\Local\FSLogix")) {
New-Item -Path "T:\Profile\AppData\Local\FSLogix" -ItemType directory | Out-Null
}
if (!(Test-Path "T:\Profile\AppData\Local\FSLogix\ProfileData.reg")) {$regtext | Out-File "T:\Profile\AppData\Local\FSLogix\ProfileData.reg" -Encoding ascii}
$script5 | diskpart

############################################################
Start-Sleep -s 10
icacls "C:\Temp\$sam" /grant $iniownr:f /q /c /t


}