<# .SYNOPSIS Finds AD users based on UVHD (User Profile Disk) file names. .DESCRIPTION Scans a folder of UVHD disks, extracts the SID from each file name (format UVHD-S-1-5-21-*.vhdx), and looks up the matching user in AD. .PARAMETER UVHDPath Path to the folder containing the UVHD files. .PARAMETER ExportCsv Optional path to export the results to a CSV file. .EXAMPLE .\Get-RDSUsersFromUVHD.ps1 -UVHDPath "\\fileserver\UPD$" .EXAMPLE .\Get-RDSUsersFromUVHD.ps1 -UVHDPath "D:\UPD" -ExportCsv "C:\Temp\uvhd_users.csv" .NOTES Author: Petr Štěpán Created: 2026-07-21 Version: 1.0.0 Changelog: 1.0.0 - Initial version #> #Requires -Modules ActiveDirectory [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Low')] param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $UVHDPath, [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [string] $ExportCsv ) Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' Write-Verbose "Loading UVHD files from '$UVHDPath'..." try { $vhdxFiles = @(Get-ChildItem -Path $UVHDPath -Filter "UVHD-S-1-5-21-*.vhdx" -File -ErrorAction Stop) } catch { Write-Error "Failed to read folder '$UVHDPath': $_" exit 1 } if ($vhdxFiles.Count -eq 0) { Write-Warning "No UVHD files were found in folder '$UVHDPath'." exit 0 } Write-Host "Found $($vhdxFiles.Count) UVHD files. Looking up users in AD...`n" -ForegroundColor Cyan $results = @(foreach ($file in $vhdxFiles) { # Extract the SID from the file name: UVHD-S-1-5-21-xxx-xxx-xxx-xxxx.vhdx $sidString = $file.BaseName -replace '^UVHD-', '' $adUser = $null $status = $null try { $sid = [System.Security.Principal.SecurityIdentifier]::new($sidString) $adUser = Get-ADUser -Identity $sid -Properties DisplayName, EmailAddress, Enabled, DistinguishedName -ErrorAction Stop $status = "OK" } catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] { $status = "User not found in AD" } catch { $status = "Error: $($_.Exception.Message)" } [PSCustomObject]@{ File = $file.Name SID = $sidString SamAccountName = $adUser.SamAccountName DisplayName = $adUser.DisplayName Email = $adUser.EmailAddress Enabled = $adUser.Enabled DistinguishedName = $adUser.DistinguishedName SizeMB = [math]::Round($file.Length / 1MB, 0) LastModified = $file.LastWriteTime Status = $status } }) # Console output $results | Format-Table -AutoSize File, SamAccountName, DisplayName, Enabled, SizeMB, LastModified, Status # Summary $ok = @($results | Where-Object { $_.Status -eq "OK" }).Count $missing = @($results | Where-Object { $_.Status -ne "OK" }).Count Write-Host "`nSummary:" -ForegroundColor Cyan Write-Host " Found in AD : $ok" -ForegroundColor Green Write-Host " Not found : $missing" -ForegroundColor $(if ($missing -gt 0) { "Yellow" } else { "Green" }) # Optional CSV export if ($ExportCsv) { if ($PSCmdlet.ShouldProcess($ExportCsv, "Export $($results.Count) records to CSV")) { $results | Export-Csv -Path $ExportCsv -NoTypeInformation -Encoding UTF8 Write-Host "`nResults exported to: $ExportCsv" -ForegroundColor Cyan } } exit 0