Feb 212018
 

I plagiarized David Ott’s script for migration of Citrix Profile Manager (UPM) profiles to FSLogix and created it for Local Profiles.

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.

This requires using frx.exe, which means that FSLogix needs to be installed on the server that contains the profiles. The script will create the folders in the USERNAME_SID format, and set all proper permissions.

Use this script. Edit it. Run it (as administrator) from the Citrix server. It will pop up this screen to select what profiles to migrate.

#### EDIT ME
$newprofilepath = "\\domain.com\share\path"

#### Don't edit me
$ENV:PATH=”$ENV:PATH;C:\Program Files\fslogix\apps\”
$oldprofiles = gci c:\users | ?{$_.psiscontainer -eq $true} | select -Expand fullname | sort | out-gridview -OutputMode Multiple -title "Select profile(s) to convert"

# foreach old profile
foreach ($old in $oldprofiles) {

$sam = ($old | split-path -leaf)
$sid = (New-Object System.Security.Principal.NTAccount($sam)).translate([System.Security.Principal.SecurityIdentifier]).Value

# set the nfolder path to \\newprofilepath\username_sid
$nfolder = join-path $newprofilepath ($sam+"_"+$sid)
# if $nfolder doesn't exist - create it with permissions
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

# sets vhd to \\nfolderpath\profile_username.vhdx (you can make vhd or vhdx here)
$vhd = Join-Path $nfolder ("Profile_"+$sam+".vhdx")

frx.exe copy-profile -filename $vhd -sid $sid
} 

  16 Responses to “FSLogix Local Profiles Migration Script”

  1. But then how do you attached this VHD to the user.


  2. #########################################################################################
    # Setup Parameter first here newprofile oldprofile subfolder1 subfolder2
    # Requires -RunAsAdministrator
    #########################################################################################
    # 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
    }

  3. to be sure, our Users where saved only with the SAMAccount Name without Domain

  4. PS C:\Windows\system32> C:\Users\adm-bart.FSL0\Desktop\fslogix migration.ps1
    processed file: \\zvb-file\profilecontainer$\adm-johan
    Successfully processed 1 files; Failed processing 0 files
    processed file: \\zvb-file\profilecontainer$\adm-johan
    Successfully processed 1 files; Failed processing 0 files

    .

    Formatting volume: \\?\Volume{5b18bc11-649f-4531-806f-b61c2b926584}\
    Copying profile for user S-1-5-21-1722534631-683760180-1736066318-1402 to volume \\?\Volume{5b18bc11-649f-4531-80
    6f-b61c2b926584}\
    Exit code: 9
    Error copying profile (0x0000001D): The system cannot write to the specified device.

  5. same problem

  6. Same issue here. Getting Error copying profile (0x0000001D)

  7. I’m also getting the 0x0000001D error. I also tried to copy the profile to the local disk (Windows 10 1903 on VMware) but this failed with the same error.

  8. The 0x0000001D error can be ignored.
    Within the user’s “AppData\Local\Microsoft\WindowsApps” folder there is a file called MicrosoftEdge.exe and also a subfolder “Microsoft.MicrosoftEdge_…” that also contains a file called MicrosoftEdge.exe, both with the size of 0 bytes.
    The frx tool uses robocopy to transfer the profile into the newly created container but fails to read/write one of those exe files mentioned above. This causes the 0x0000001D error.
    But aside from that robocopy copies the whole profile. Therefore it should be usable.

  9. If the folder “AppData\Local\Microsoft\WindowsApps” is deleted before using frx to migrate the profile then frx succeeds and the VHDX file is properly created and its security settings can be modified accordingly afterwards.

    I logged on with that user’s profile to assure that deleting the “WindowsApps” folder hasn’t any negative effect on the profile. Microsoft Edge starts without any errors, so deleting that folder doesn’t seem to have any negative impactso far.

    Maybe this does help you folks to get the migration of the profiles up and running.

  10. How would one execute this command remotely to migrate 100’s of users profiles from their persistent VDI to an FSLogix Share?
    I am a Newbie when it comes to Powershell.

  11. Any way we could use this to just migrate a named local user profile to VHD?

  12. Sorry didn’t look at the script very well and see the Out-GridView command – have changed it to set the variable to $ENV:USERNAME and it works for me.

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

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