Oct 242017
 

NOTE: This only works between like profile versions.  eg. You can’t migrate your 2008R2 profiles to Server 2016 and expect it to work.  See this chart.

I moved from UPM to FSLogix earlier this year, and decided to write my own powershell script to convert the UPM profiles to .vhd.  FSLogix has its own conversion process (which I didn’t find a whole lot of info on), but I decided to create my own.

What this script does:

  1. Gets a list of all UPM profile directories in the root path (that you supply) and displays them to you to select which one(s) you would like to convert via out-gridview
  2. For each profile you select:
    1. Gets the username from the profile path – you will have to edit this part for your environment… explanation in the script
    2. Use the username to get the SID (FSLogix profiles use the username and sid to name the profile folder)
    3. Creates the FSLogix profile folder (if it doesn’t exist)
    4. Sets the user as the owner of that folder, and gives them full control
    5. Creates the .vhd (my default is 30GB dynamic – edit on line 70 if you wish to change it) – if it doesn’t exist (if it does skip 7, 9-10)
    6. Attaches the .vhd
    7. Creates a partition and formats it ntfs
    8. Assigns the letter T to that drive (edit on line 73 if you wish to change that)
    9. Creates the T:\Profile directory
    10. Grants System/Administrators and the user full control of the profile directory
    11. Copies the profile from the UPM path to the T:\Profile directory with /E /Purge – if you are re-running this script on a particular profile it will overwrite everything fresh
    12. Creates T:\Profile\AppData\Local\FSLogix if it doesnt exist
    13. Creates T:\Profile\AppData\Local\FSLogix\ProfileData.reg if it doesn’t exist (this feeds the profilelist key at logon)

Here is the script!

  24 Responses to “Citrix UPM Profiles to FSLogix Profiles Conversion Powershell Script”

  1. Hi David,

    I´m trying to migrate some UPM profiles to FSLogix profiles with your script but I cannot get further. I´ve edit the $newprofilepath and $oldprofile variable as needed for our environment, but I do not get any respsone from the script. Actually nothing happens. In general I just want to ask you for help.

    Regards
    Martin

    • Martin there is more to it than just changing the $newprofilepath and the $oldprofiles variables. Read through the commented sections.

  2. […] some research I choose to try out a script created by David Ott. You can check the original post here, or on the FSLogix […]

  3. […] Citrix UPM Profiles to FSLogix Profiles Conversion Powershell Script […]

  4. How does the User profile know which disk to attached. Could you please clarify.

  5. $sid = (New-Object System.Security.Principal.NTAccount($sam)).translate([System.Security.Principal.SecurityIdentifier]).Value

    reports:

    New-Object : Ausnahme beim Aufrufen von “.ctor” mit 1 Argument(en): “Die Zeichenfolge kann keine Länge von 0 (null)
    haben.
    Parametername: name”
    In C:\batch\Migrate.ps1:43 Zeichen:9
    + $sid = (New-Object System.Security.Principal.NTAccount($sam)).transla …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (:) [New-Object], MethodInvocationException
    + FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand

    Any Ideas? I´m stucked at the moment and can´t find the error.

    Without this $sid I get a profile-folder called “_” and a “Profile.vhd”

    Is it possible to create VHDX instea of VHD?

    Thanks a lot
    Marc


  6. #########################################################################################
    # Setup Parameter first here newprofile oldprofile subfolder1 subfolder2
    # Requires -RunAsAdministrator
    # My Userprofiles come only with SAMAccount Name without Domain "\Username\2012R2\UPM_Profile
    #########################################################################################
    # Example from my UPM Path "\\path_to_your_share\username\2012R2\UPM_Profile"
    # fslogix Root profile path
    $newprofilepath = "\\path_to_your_share\FSLogix"
    # UPM Root profile path
    $oldprofilepath = "\\path_to_your_share\UPM\Userprofiles"
    # Subfolder 1 - First Path to UPM_Profile Folder in UPM Profiles - see my example above
    $subfolder1 = "2012R2"
    # Subfolder 2 - First Path to UPM_Profile Folder in UPM Profiles - see my example above
    $subfolder2 = "UPM_Profile"

    #########################################################################################
    # Do not edit here
    #########################################################################################
    $oldprofiles = gci $oldprofilepath | select -Expand fullname | sort | out-gridview -OutputMode Multiple -title "Select profile(s) to convert"| %{
    Join-Path $_ $subfolder1\$subfolder2
    }

    foreach ($old in $oldprofiles) {
    $sam = Split-Path ($old -split $subfolder1)[0] -leaf
    $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 ($sam+"\"+$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
    $vhd = Join-Path $nfolder ("Profile_"+$sam+".vhdx")

    $script1 = "create vdisk file="$vhd" maximum 30720 type=expandable"
    $script2 = "sel vdisk file=
    "$vhd"rnattach vdisk"
    $script3 = "sel vdisk file=
    "$vhd"rncreate part primrnselect part 1rnformat fs=ntfs quick"
    $script4 = "sel vdisk file=
    "$vhd"rnsel part 1rnassign letter=T"
    $script5 = "sel vdisk file
    "$vhd"rndetach vdisk"
    $script6 = "sel vdisk file=
    "$vhd"rnattach vdisk readonly"rncompact 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 /E /Purge /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
    }

    • Thank you so much. Your script worked. However, when I run the script, the end result is “Profile_Username.vhdx”. is there a way i can modify the script so that end result is “Username.vhdx”? without the “Profile_”?
      Thanks

  7. The script works fine, except at the permissions files/ownership.

    On Windows, the ownership of the users folder are Administrators, after that, it is the user for subfolders+files.
    With FSLogix, is it SYSTEM not administrators, the same thing, the user is owner.

    With the original script, the owner is the group administrators, not the user. I had errors on loading ntuser.dat, folder desktop,etc.
    I moved the line about Removing the inheritance (T:\profile), looks it breaks some permissions while copying, the logic we should add permissions before removing ?

    Robocopy copy attributes don’t work well (/DATO, /DATSOU, etc.) on my testings, I wanted to copy the owner attribute, but i had some strange permissions added (user LogonsessionID).

    After the robocopy, I added a line to make the user full owner with the command /T, and then I change T:\profile’s owner as system.
    Also adding the user permissions after copying the files with /T to be recursive, sometimes, the user wasn’t included in the permissions (?)

    I modified a bit the script and it works now, it respects the permissions for the profile. It might look not optimized, but 100% covered. I don’t want to get support calls for profile users that failed on migration.

    $cmd1 = “T:\Profile /grant ${env:userdomain}\${sam}:(OI)(CI)F /T”
    $cmd2 = “T:\Profile /setowner ${env:userdomain}\${sam} /T”
    Start-Process icacls -ArgumentList “T:\Profile /grant SYSTEM:(OI)(CI)F”
    Start-Process icacls -ArgumentList “T:\Profile /grant Administrateurs:(OI)(CI)F”
    Start-Process icacls -ArgumentList “T:\Profile /inheritance:r”
    } else {
    # if the vhd does exist then attach, wait 5 seconds, assign letter T
    $script2 | diskpart
    Start-Sleep -s 5
    $script4 | diskpart
    }

    # copies in the UPM profile to the Profile directory on the vhd /E /Purge – this is so it will update with the latest info
    “Copying $old to $vhd”
    & robocopy $old T:\Profile /E /Purge /r:0 | Out-Null

    Start-Process icacls -ArgumentList $cmd1
    start-process icacls -ArgumentList $cmd2
    start-process icacls “T:\Profile /setowner SYSTEM”

    • Hoping to get some quick help with the modifications to the script you made for migrating UPM to VHD.

      Where exactly do you insert the lines that you adjusted?

  8. Hi

    Please help me to fill this bit because my folder path do not have sub folders.

    My old UPD path: \\PNI-UPD-001\UPD
    New fslogix UPD path: \\UPD-2019-T01\Profiles

    So

    # Example from my UPM Path “\\path_to_your_share\username\2012R2\UPM_Profile” ???
    # fslogix Root profile path
    $newprofilepath = “\\UPD-2019-T01\Profiles”
    # UPM Root profile path
    $oldprofilepath = “\\PNI-UPD-001\UPD”
    # Subfolder 1 – First Path to UPM_Profile Folder in UPM Profiles – see my example above
    $subfolder1 = “2012R2” ???
    # Subfolder 2 – First Path to UPM_Profile Folder in UPM Profiles – see my example above
    $subfolder2 = “UPM_Profile” ???

    Thank you.

    Dash

  9. Nice Blog man, Very nice!!

  10. there is any way to migrate citrix UPM profile to Local Profile .

  11. Hello, I was able to run the script successfully and the profile.vhdx file got created,no issues here, thank you. But when the FSLogix agent access it during login, it names the file as CORRUPT_###_Profile_upi, then it creates a new profile_sid and then deletes the corrupt file. Not sure where I am getting it wrong or something else is wrong here. Please help.

  12. Thank you Ryan; I was able to fix it. The issue was that the script was copying only the AppData folder from the UPM folder and leaving the rest being, once I tweak the script to copy all data from UPM, the FSLogix Agent recognized the vhdx file and build further on that. Then I was able to see my desktop, icons and bookmarks.

  13. Thanks for sharing!
    I modified the script, to convert our V6-Roaming profiles to FSLogix-VHDX profiles. Everything works as expected, except for the users start menu. It is completely empty, adding any items is not possible either.
    We use a GPO to deploy a customized Start menu to users, which works fine for V6-Profiles. It also works if I first login the user once on the new server (so that the .vhdx is created automatically) and then run the modified script for copying the users data. This is not an option due to the amount of users and the time it would take converting them all one by one.
    Any suggestions on how to fix the start menu when using the script to create the vhdx-file?

    • Nico, unfortunately, the script owner retired. I’m not sure how this could be fixed. I’d check out WorldofEUC and ask around in there.

  14. Hi, the script is not available on the link. Could you please re share it?

Leave a Reply to Ryan Gallier Cancel reply

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

(required)

(required)

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