Moving to Azure NetApp Files for FSLogix Profile storage is surprisingly easy! By supporting multiple SMB paths for these profiles, doing a cut-over to ANF as the SMB path for profiles can happen without impacting users.
The path(s) used for FSLogix profile storage is simply a registry value with the SMB path(s) as the value. When multiple values exist, FSLogix simply uses them in the order listed. First is searches all the listed paths for the user profile, using the first one found. If none are found it creates a new profile in the first SMB path that is available are writable.
The registry key that defines these SMB paths is called VHDLocations: Configure profile containers tutorial – FSLogix | Microsoft Learn
To specify multiple paths, you can add each path separated by a semicolon “;” or simply added as a MULTI_SZ Key. In my migration I used the semicolon, like this:
\\mystorageaccount.file.core.windows.net\premium-share;\\myanfaccount.anf.azure.com\volumes\my-anf-share
So, after the registry is updated to include all available SMB paths, all you need to do to change the storage service used for a particular user is to put their profile on the preferred service. In our example, simply move the user’s profile folder (e.g. “johndoe_S-1-5-21-1234567890-2345678901-3456789012-1001”) from the old path to the new one any time that user is not logged in.
When the profile is in use a .METADATA file is present within the folder, you can use that as part of a script to move any users that are logged out (i.e. that file is not present in the user profile folder) and move these profiles in bulk without needing to scheduled downtime nor work deep into the evening.
I know this sounds obvious. It is but for something so important, I figured I’d write it down to give others (you) confidence that it is indeed that easy.
To mitigate risk, you can move profiles one at a time or in bunches so that POC users can be tested to validate for skeptical stakeholders.
Obviously, I use this for moving FSLogix profile data from slower and more costly storage options to Azure NetApp Files. Especially with cool access enabled, ANF is higher performing and lower cost than other ways of hosting FSLogix profile data in Azure. And yes, ANF cool access plays nicely with FSLogix profile data.
In more detail, here are the steps:
- Create new SMB share and get the path
- With Azure NetApp Files you can get the mounting path by navigating to ANF Volume > Storage service > Mount instructions
- The path shown in step 4 can be directly used in the registry, or a deeper path could be created and used
- Add new SMB path as secondary in Registry
- FSLogix uses the path(s) defined by a registry entry to
HKEY_LOCAL_MACHINE\SOFTWARE\FSLogix\Profiles\VHDLocations - Typically this is a REG_SZ with a value equal to a single SMB path for the location of the profile storage. e.g.
\\server\path - Multiple values are allowed, with FSLogix using the storage paths in priority order matching the order of the listed values.
- Append a semicolon
(;)and the new SMB path to the value of this Registry Key and save. Make this change manually on an individual AVD host for testing via your established management process in production (e.g. Intune or GPO): the Key Value is now: \\mystorageaccount.file.core.windows.net\premium-share;\\myanfaccount.anf.azure.com\volumes\my-anf-share - If a user profile is present in both paths, the first path (in the registry) that contains the profile will be used. If only one or the other path contains the profile, only that path will be used, and if neither path contains the profile, a new profile will be created on the first path listed.
- FSLogix uses the path(s) defined by a registry entry to
- Robocopy profile(s) to new path
- Ensuring the user is not currently logged in, you can use robocopy to copy (for a test) or move (for prod) the profile(s) from the old share to the new one. Feel free to use whatever robocopy switched meet your requirements.
- e.g.
robocopy \\server\path \\new-anf.SMB-Path.com\path /E /nfl /XO /np /mt:8 /ndl - Another option would be to use PowerShell to check the path for the METADATA file and only copy the appropriate folders. Here is an example script you could use as a starting point, please test it before use, I have not yet tested this exact script (see below).
- (Optional) Promote New SMB path to primary in registry and/or simply delete the old SMB path from the registry
- Depending on your on-going use case, you can now switch the registry priority, remove the old one entirely or keep it as is.
- As stated above, when multiple paths are listed and the user profile is present in both paths, the first path that contains the profile will be used. This is not a good state to leave the environment in. Let’s agree that the production profile will only be stored in one place to avoid confusion and wasted storage space.
- When multiple paths are listed and the user profile is present on only one path, that profile will be used regardless of the path’s priority on the list. (This setup could be used to spread user profiles across multiple storage layers, perhaps for regional distribution or DR purposes.)
- If neither path contains the profile, a new profile will be created on the first path listed
Example PowerShell to Move Only Logged Out Users
Reminder: Don’t use scripts form the internet you don’t fully understand. This is a fine starting point, but I haven’t tested it and make no warranty.
# Define paths
$SourcePath = "\\mystorageaccount.file.core.windows.net\premium-share"
$DestinationPath = "\\myanfaccount.anf.azure.com\volumes\my-anf-share"
$LogFile = "C:\Logs\FSLogixProfileMigration.log"
# Ensure log directory exists
if (!(Test-Path (Split-Path -Path $LogFile))) {
New-Item -ItemType Directory -Path (Split-Path -Path $LogFile) -Force | Out-Null
}
# Get all user profile folders
$UserProfiles = Get-ChildItem -Path $SourcePath -Directory
foreach ($Profile in $UserProfiles) {
$MetadataFile = Join-Path -Path $Profile.FullName -ChildPath ".METADATA"
if (!(Test-Path $MetadataFile)) {
# Define the target destination
$TargetPath = Join-Path -Path $DestinationPath -ChildPath $Profile.Name
# Log the action
Add-Content -Path $LogFile -Value "$(Get-Date) - Moving profile: $($Profile.Name) to $TargetPath"
# Move the entire profile folder
try {
Move-Item -Path $Profile.FullName -Destination $TargetPath -Force -ErrorAction Stop
Add-Content -Path $LogFile -Value "$(Get-Date) - Successfully moved profile: $($Profile.Name)"
} catch {
Add-Content -Path $LogFile -Value "$(Get-Date) - ERROR moving profile $($Profile.Name): $_"
}
} else {
# Log that the metadata file was found
Add-Content -Path $LogFile -Value "$(Get-Date) - Metadata file found, skipping: $($Profile.Name)"
}
}
Write-Host "Profile migration check complete. See log file at $LogFile" -ForegroundColor Green
Pingback: Real World Use Case Confirmation: Azure NetApp Files (ANF) for FSLogix User profiles and Azure Virtual Desktop (AVD) - Posted