User Profile Disks in Remote Desktop Services allow for a consistent user experience in a distributed computing environment. UPDs utilize Hyper-V VHDX technology to ensure a user’s profile and data is available for their use regardless of which session host the connection broker directs the client to.
User Profile Disks replace the more well known roaming profile and folder redirection solutions. UPDs are easier to manage and use, for the most part. However, they occasionally become orphaned which requires an administrator to dismount the virtual disk. Unfortunately, this can be easier said than done. There isn’t a direct way to perform this function in the RDS Server Manager.
If you search the web for “find user profile disk”, you will inevitably encounter the Sidder app. This tool was a godsend when it was released during the 2012 era. Just download the app, double click the .exe, browse to the location of your UPDs, and a popup lists each user’s mounted virtual hard disk.
The Sidder app worked great in its time, but in today’s remote work environments most RDS farms have more than a single session host and multiple UPD storage locations. Searching them all one at a time is tedious. PowerShell to the rescue. The code below will prompt for a username, just enter the name part, the domain will be added automatically. You’ll need to run it from an RDS server or a workstation with the RDS RSAT loaded.
$UserToFind = Read-Host "Enter Username (e.g. firstname.lastname)?"
$User = $env:USERDOMAIN + '\' + $UserToFind
$RDCollection = Get-RDSessionCollection
$RDHosts = Get-RDSessionHost -CollectionName $RDCollection.CollectionName | select SessionHost
$Array = Invoke-Command -ComputerName $RDHosts.SessionHost -ScriptBlock {Get-Disk | select Location,DiskNumber | where {($_.Location -notmatch "Integrated") -and ($_.Location -notlike "PCI Slot *")}}
$UPDs = @()
foreach ($VHD in $Array){
$DiskID = (Get-Item $VHD.Location).Name.Substring(5).Split(".")[0]
$objSID = New-Object System.Security.Principal.SecurityIdentifier ($DiskID)
$objUser = $objSID.Translate( [System.Security.Principal.NTAccount])
if ($objUser.Value -eq $User){
$UPDs += "$($objUser.Value) has user disk number $($VHD.DiskNumber) on $($VHD.PSComputername)"
}
}
If ($UPDS -ne $null) {$UPDs}
Else {"$User does not have any user profile disks mounted in RDS"}
pause
This version will list all of the user profile disks in the RDS farm.
$RDCollection = Get-RDSessionCollection
$RDHosts = Get-RDSessionHost -CollectionName $RDCollection.CollectionName | select SessionHost
$Array = Invoke-Command -ComputerName $RDHosts.SessionHost -ScriptBlock {Get-Disk | select Location,DiskNumber | where {($_.Location -notmatch "Integrated") -and ($_.Location -notlike "PCI Slot *")}}
$UPDs = @()
foreach ($VHD in $Array){
$DiskID = (Get-Item $VHD.Location).Name.Substring(5).Split(".")[0]
$objSID = New-Object System.Security.Principal.SecurityIdentifier ($DiskID)
$objUser = $objSID.Translate( [System.Security.Principal.NTAccount])
$UPDs += "$($objUser.Value) has user disk number $($VHD.DiskNumber) on $($VHD.PSComputername)"
}
$UPDs