Oct 242017
 

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!

  7 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`"`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 /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
    }

Leave a Reply to Brian Cancel 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)