Why Use the Registry to Find a UPD?
When a user logs in to an RDS session, Windows mounts their User Profile Disk and records the mapping in the registry on the session host. The UPD filenames themselves are based on the user's Security Identifier (SID) — not their username — so the file share shows something like UVHD-S-1-5-21-3623811015-3361044348-30300820-1013.vhdx, with no obvious way to know who it belongs to.
The registry gives you two useful pieces of information:
- Which UPD file path Windows expects to use for each user
- A way to cross-reference a username with a SID to match up files on the share
This is particularly useful when you need to resize, restore, or delete a specific user's disk and you don't want to log in to Server Manager.
The UVHD Registry Key
When an RDS session host mounts a UPD, it writes data under this registry path on the session host (not the connection broker or file server):
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\UVHDUnder this key, you'll find subkeys for each active or recently used UPD session. The key structure tracks the mounted state, the VHD path, and the user SID tied to the session.
Querying the Registry with reg query
Run this on the RDS session host as an administrator. You can do it remotely using the /s flag:
reg query "HKLM\SYSTEM\CurrentControlSet\Services\UVHD" /sThis outputs all subkeys and their values. Look for entries that reference your UPD share path — they will include the VHDX filename with the user's SID embedded in it.
To query a remote session host:
reg query "\\SESSIONHOST01\HKLM\SYSTEM\CurrentControlSet\Services\UVHD" /sMapping a Username to a SID
The most reliable method is to convert the username to a SID, then match that SID to the VHDX filename on the share. Run this in PowerShell:
# Get the SID for a domain user $username = "jsmith" $domain = "CONTOSO" $objUser = New-Object System.Security.Principal.NTAccount("$domain\$username") $sid = $objUser.Translate([System.Security.Principal.SecurityIdentifier]) Write-Host "SID: $($sid.Value)"Once you have the SID, find their UPD on the file share:
$udpShare = "\\FileServer\UPDs" $sid = "S-1-5-21-3623811015-3361044348-30300820-1013" Get-ChildItem -Path $udpShare -Filter "UVHD-$sid.vhdx"If the file exists, that's the user's profile disk.
Reverse Lookup — SID to Username
If you have a VHDX filename and want to know which user it belongs to, extract the SID from the filename and reverse-resolve it:
# Extract SID from filename like "UVHD-S-1-5-21-xxx-xxx-xxx-1013.vhdx" $filename = "UVHD-S-1-5-21-3623811015-3361044348-30300820-1013.vhdx" $sid = $filename -replace "^UVHD-", "" -replace "\.vhdx$", "" # Resolve SID to username $objSid = New-Object System.Security.Principal.SecurityIdentifier($sid) $objUser = $objSid.Translate([System.Security.Principal.NTAccount]) Write-Host "Username: $($objUser.Value)"Cross-Referencing with ProfileList in the Registry
Another useful registry location on any Windows machine (including the session host) is the ProfileList key, which maps SIDs to local profile paths:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileListEach subkey is named with a SID. Check the ProfileImagePath value to confirm the profile folder. You can query all profiles with:
$profileListPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" Get-ChildItem -Path $profileListPath | ForEach-Object { $sid = $_.PSChildName $path = (Get-ItemProperty -Path $_.PSPath).ProfileImagePath try { $objSid = New-Object System.Security.Principal.SecurityIdentifier($sid) $account = $objSid.Translate([System.Security.Principal.NTAccount]).Value } catch { $account = "(unresolvable)" } [PSCustomObject]{ SID = $sid Username = $account ProfilePath = $path } } | Format-Table -AutoSizeThis gives you a complete table of every profile that has been loaded on that session host, including the matching SID — which you can then use to find the VHDX on the share.
Bulk Audit: Match All UPDs to Usernames
To generate a report of all UPDs on a share with their associated usernames:
$udpShare = "\\FileServer\UPDs" Get-ChildItem -Path $udpShare -Filter "UVHD-S-*.vhdx" | ForEach-Object { $sid = $_.BaseName -replace "^UVHD-", "" try { $objSid = New-Object System.Security.Principal.SecurityIdentifier($sid) $account = $objSid.Translate([System.Security.Principal.NTAccount]).Value } catch { $account = "(unknown)" } [PSCustomObject]{ File = $_.Name Username = $account SizeMB = [math]::Round($_.Length / 1MB, 1) Modified = $_.LastWriteTime } } | Sort-Object SizeMB -Descending | Format-Table -AutoSizeThis is useful for identifying orphaned UPDs belonging to users who have left the organisation, or for spotting disks that are growing unusually large.