david62277

Citrix UPM to FSLogix

Oct 24th, 2017
4,714
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #Requires -RunAsAdministrator
  2. <#
  3. Written by David Ott
  4. This script will convert Citrix UPM profiles to FSLogix .vhd profiles (you should be able to edit it to do vhdx as well)
  5. Pay attention to all of the commented areas.  It uses diskpart to create/mount/dismount the .vhd file, and
  6. robocopy to copy the UPM profile to the .vhd.
  7. Once executed (assuming you have edited $newprofilepath and $oldprofiles to match your environment) it will give you a list of
  8. profiles to convert.  You can then select which profile(s) you wish to convert to FSLogix profiles.
  9. You could also edit this script to use hyperv commands to create/mount/dismount the vhd/vhdx files instead of diskpart if you have
  10. the hyperv module installed.
  11. Before using in production test!!
  12. #>
  13. # fslogix profile path
  14. $newprofilepath = "\\server\fslogxprofiles" ##### FSLogix Root Profile Path
  15. <#
  16. upm profile path - our production UPM root folders are username.domain, and the actual Windows 7 profile lives under
  17. v2x64\UPM_Profile:
  18. \\server\share\%USERNAME%.%USERDOMAIN%\!CTX_PROFILEVER!!CTX_OSBITNESS!
  19. this would have to be edited based on environment - the main thing is to have it have the full path to all of the actual UPM_Profile
  20. directories
  21. #>
  22. $oldprofiles = gci \\oldserver\upmprofiles | ?{$_.name -like "*.$env:userdomain"} | select -Expand fullname | sort | out-gridview -OutputMode Multiple -title "Select profile(s) to convert"| %{
  23. Join-Path $_ "v2x64\UPM_Profile"
  24. }
  25.  
  26.  
  27. # foreach old profile
  28. foreach ($old in $oldprofiles) {
  29. <#
  30. Since I know that the folder has the username in it i get that and save it to the sam variable, and use that to get the user's sid
  31. then save that to $sid.
  32. You will most likely have to edit the $sam line to pull the username out of the old profile path.  Play with the string and
  33. split-path until you nail down just the username.  For instance let's say your current profile path is
  34. \\server\profileshare\username\v2x64\UPM_Profile  you could do something like this
  35. $sam = (($old -split "profileshare")[1] -split "v2x64")[0] -replace "\\",""
  36. That splits the string at profileshare, and selects the 2nd part (0 would be the first) which is \username\v2x64\UPM_Profile
  37. it then splits that again using v2x64 and selects the first part (remember 0 is the first) which is \username\
  38. Finally it replaces the "\" characters (you need to match \\ as \ is a special character the first slash just says to use it as a
  39. string) with nothing... leaving you with the username.  
  40. #>
  41. $sam = Split-Path ($old -split ".$env:userdomain")[0] -leaf
  42. $sid = (New-Object System.Security.Principal.NTAccount($sam)).translate([System.Security.Principal.SecurityIdentifier]).Value
  43. <#
  44. A .reg file located in %localappdata%\FSLogix - last thing the script does is create the .reg file for the profilelist key
  45. #>
  46. $regtext = "Windows Registry Editor Version 5.00
  47.  
  48. [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$sid]
  49. `"ProfileImagePath`"=`"C:\\Users\\$sam`"
  50. `"FSL_OriginalProfileImagePath`"=`"C:\\Users\\$sam`"
  51. `"Flags`"=dword:00000000
  52. `"State`"=dword:00000000
  53. `"ProfileLoadTimeLow`"=dword:00000000
  54. `"ProfileLoadTimeHigh`"=dword:00000000
  55. `"RefCount`"=dword:00000000
  56. `"RunLogonScriptSync`"=dword:00000000
  57. "
  58. <# set the nfolder path to \\newprofilepath\username_sid - this is not default
  59. If you are going with the default then replace then reverse the $sam/$sid variables as below
  60. $nfolder = join-path $newprofilepath ($sid+"_"+$sam)
  61. #>
  62. $nfolder = join-path $newprofilepath ($sam+"_"+$sid) ##### See note above
  63. # if $nfolder doesn't exist - create it
  64. if (!(test-path $nfolder)) {New-Item -Path $nfolder -ItemType directory | Out-Null}
  65. & icacls $nfolder /setowner "$env:userdomain\$sam" /T /C
  66. & icacls $nfolder /grant $env:userdomain\$sam`:`(OI`)`(CI`)F /T
  67. # sets vhd to \\nfolderpath\profile_username.vhd
  68. $vhd = Join-Path $nfolder ("Profile_"+$sam+".vhd")
  69. # diskpart commands
  70. $script1 = "create vdisk file=`"$vhd`" maximum 30720 type=expandable"
  71. $script2 = "sel vdisk file=`"$vhd`"`r`nattach vdisk"
  72. $script3 = "sel vdisk file=`"$vhd`"`r`ncreate part prim`r`nselect part 1`r`nformat fs=ntfs quick"
  73. $script4 = "sel vdisk file=`"$vhd`"`r`nsel part 1`r`nassign letter=T"
  74. $script5 = "sel vdisk file`"$vhd`"`r`ndetach vdisk"
  75. $script6 = "sel vdisk file=`"$vhd`"`r`nattach vdisk readonly`"`r`ncompact vdisk"
  76. <#
  77. if the vhd doesn't exist create, attach, wait 5 seconds (windows has to catch up), create/format the partition,
  78. assigns letter T (change this as needed), and sets the disk label to Profile-username
  79. #>
  80. if (!(test-path $vhd)) {
  81. $script1 | diskpart
  82. $script2 | diskpart
  83. Start-Sleep -s 5
  84. $script3 | diskpart
  85. $script4 | diskpart
  86. & label T: Profile-$sam
  87. New-Item -Path T:\Profile -ItemType directory | Out-Null
  88. # set permissions on the profile
  89. start-process icacls "T:\Profile /setowner SYSTEM"
  90. Start-Process icacls -ArgumentList "T:\Profile /inheritance:r"
  91. $cmd1 = "T:\Profile /grant $env:userdomain\$sam`:`(OI`)`(CI`)F"
  92. Start-Process icacls -ArgumentList "T:\Profile /grant SYSTEM`:`(OI`)`(CI`)F"
  93. Start-Process icacls -ArgumentList "T:\Profile /grant Administrators`:`(OI`)`(CI`)F"
  94. Start-Process icacls -ArgumentList $cmd1
  95. } else {
  96. # if the vhd does exist then attach, wait 5 seconds, assign letter T
  97. $script2 | diskpart
  98. Start-Sleep -s 5
  99. $script4 | diskpart
  100. }
  101.  
  102. # copies in the UPM profile to the Profile directory on the vhd /E /Purge - this is so it will update with the latest info
  103. "Copying $old to $vhd"
  104. & robocopy $old T:\Profile /E /Purge /r:0 | Out-Null
  105. # creates the %localappdata%\FSLogix path if it doesnt exist
  106. if (!(Test-Path "T:\Profile\AppData\Local\FSLogix")) {
  107. New-Item -Path "T:\Profile\AppData\Local\FSLogix" -ItemType directory | Out-Null
  108. }
  109. # creates the profiledata.reg file if it doesn't exist
  110. if (!(Test-Path "T:\Profile\AppData\Local\FSLogix\ProfileData.reg")) {$regtext | Out-File "T:\Profile\AppData\Local\FSLogix\ProfileData.reg" -Encoding ascii}
  111. $script5 | diskpart
  112. }
Add Comment
Please, Sign In to add comment