commit 16ad4bc2f21b248c25ba625af6b322a5425bb41d Author: Petr Štěpán Date: Tue Jul 21 15:01:44 2026 +0200 Add script to find AD users based on UVHD file names diff --git a/Get-RDSUsersFromUVHD.ps1 b/Get-RDSUsersFromUVHD.ps1 new file mode 100644 index 0000000..34d5504 --- /dev/null +++ b/Get-RDSUsersFromUVHD.ps1 @@ -0,0 +1,114 @@ +<# +.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