Public/Get-VBUserPrinterMappings.ps1
|
# ============================================================ # FUNCTION : Get-VBUserPrinterMappings # MODULE : WorkstationReport # VERSION : 1.3.0 # CHANGED : 14-04-2026 -- Standards compliance fixes # AUTHOR : Vibhu Bhatnagar # PURPOSE : Retrieves printer mappings for all user profiles on local or remote computers # ENCODING : UTF-8 with BOM # ============================================================ function Get-VBUserPrinterMappings { <# .SYNOPSIS Retrieves printer mappings and default printer settings for all user profiles on specified computers. .DESCRIPTION Get-VBUserPrinterMappings audits printer configurations for all user profiles on local or remote computers. It examines user registry hives to identify network printer mappings, default printer settings, and available printer devices, while excluding virtual and system printers (PDF, XPS, OneNote, Fax). Registry hives for inactive profiles are loaded and safely unloaded after inspection. A single scriptblock is used for both local and remote execution to eliminate code duplication -- local runs use direct invocation (&), remote runs use Invoke-Command. .PARAMETER ComputerName Computer names to audit. Accepts pipeline input. Defaults to the local computer. .PARAMETER Credential Credentials for remote computer access. Not required for local execution. .PARAMETER TableOutput When specified, suppresses console output and returns only structured objects. Without this switch, verbose progress is written to the console using Write-Host. .EXAMPLE Get-VBUserPrinterMappings Audits printer mappings for all user profiles on the local computer. .EXAMPLE Get-VBUserPrinterMappings -ComputerName 'WS001','WS002' -Credential $cred -TableOutput Audits printer mappings on two remote workstations and returns structured objects only. .EXAMPLE 'WS001','WS002' | Get-VBUserPrinterMappings | Where-Object { $_.PrinterCount -gt 0 } | Format-Table Pipeline input -- audits workstations and shows only users with mapped printers. .EXAMPLE Get-VBUserPrinterMappings -TableOutput | Export-Csv -Path 'C:\Reports\PrinterAudit.csv' -NoTypeInformation Exports printer audit results to CSV without console output. .OUTPUTS PSCustomObject Returns objects with: - ComputerName : Target computer - Username : User profile name - NetworkPrinters : Semicolon-separated list of network printer connections - DefaultPrinter : Name of the default printer, or 'No default printer' - PrinterDevices : Semicolon-separated list of available printer devices - PrinterCount : Total count of network printers and devices combined - LastProfileUpdate : Last write time of the user profile directory - CollectionTime : Timestamp of data collection - Status : 'Success' or 'Failed' - Error : Error message (only present on failure) .NOTES Version : 1.3.0 Author : Vibhu Bhatnagar Category: Windows Workstation Administration Requirements: - PowerShell 5.1 or higher - Administrative privileges on target computers - PowerShell Remoting enabled for remote targets - Registry access permissions for HKEY_USERS and HKEY_LOCAL_MACHINE #> [CmdletBinding()] param( [Parameter(ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('Name', 'Server', 'Host')] [string[]]$ComputerName = $env:COMPUTERNAME, [PSCredential]$Credential, [switch]$TableOutput ) process { # Core logic defined once -- executed locally or via Invoke-Command $scriptBlock = { param([bool]$ShowConsole) $computerName = $env:COMPUTERNAME $collectionTime = (Get-Date).ToString('dd-MM-yyyy HH:mm:ss') $results = [System.Collections.Generic.List[object]]::new() $virtualPrinters = @( 'Microsoft Print to PDF', 'Microsoft XPS Document Writer', 'OneNote (Desktop)', 'OneNote for Windows 10' ) $systemPrinters = @('Fax') if ($ShowConsole) { Write-Host "`nStarting printer mapping audit on: $computerName" -ForegroundColor Green Write-Host '=================================================' -ForegroundColor Green } # Collect user profile paths $userProfiles = Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList' | Where-Object { $_.PSChildName.Length -gt 8 } | ForEach-Object { $_.GetValue('ProfileImagePath') } foreach ($profilePath in $userProfiles) { $username = Split-Path $profilePath -Leaf $hiveLoaded = $false if ($ShowConsole) { Write-Host "`nChecking: $username" -ForegroundColor Cyan Write-Host ('-' * 40) -ForegroundColor Gray } # Resolve SID for this profile $userSID = ( Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList' | Where-Object { $_.GetValue('ProfileImagePath') -eq $profilePath } ).PSChildName if (-not $userSID) { if ($ShowConsole) { Write-Host " Could not resolve SID for: $username" -ForegroundColor Red } $results.Add([PSCustomObject]@{ ComputerName = $computerName Username = $username NetworkPrinters = 'No SID Found' DefaultPrinter = 'No SID Found' PrinterDevices = 'No SID Found' PrinterCount = 0 LastProfileUpdate = (Get-Item $profilePath -ErrorAction SilentlyContinue).LastWriteTime CollectionTime = $collectionTime Error = 'Could not resolve SID for user profile' Status = 'Failed' }) continue } try { # Load hive if not already mounted if (-not (Test-Path "Registry::HKEY_USERS\$userSID")) { $null = reg load "HKU\$userSID" "$profilePath\NTUSER.DAT" $hiveLoaded = $true } # --- Network printers --- $networkPrinters = @( Get-ChildItem "Registry::HKEY_USERS\$userSID\Printers\Connections" -ErrorAction SilentlyContinue | ForEach-Object { $_.PSChildName.Replace(',', '\') } | Where-Object { $pn = $_ -not ($virtualPrinters | Where-Object { $pn -like "*$_*" }) } ) if ($ShowConsole) { Write-Host ' Mapped Network Printers:' -ForegroundColor Yellow if ($networkPrinters) { $networkPrinters | ForEach-Object { Write-Host " - $_" -ForegroundColor White } } else { Write-Host ' None' -ForegroundColor Gray } } # --- Default printer --- $defaultPrinterReg = Get-ItemProperty "Registry::HKEY_USERS\$userSID\Software\Microsoft\Windows NT\CurrentVersion\Windows" ` -Name 'Device' -ErrorAction SilentlyContinue $defaultPrinterName = if ($defaultPrinterReg) { $pn = ($defaultPrinterReg.Device -split ',')[0] $isVirtual = $virtualPrinters | Where-Object { $pn -like "*$_*" } $isSystem = $systemPrinters | Where-Object { $pn -like "*$_*" } if ($isVirtual -or $isSystem) { 'No default printer' } else { $pn } } else { 'No default printer' } if ($ShowConsole) { Write-Host ' Default Printer:' -ForegroundColor Yellow Write-Host " - $defaultPrinterName" -ForegroundColor White } # --- Printer devices --- $allDevices = Get-ItemProperty "Registry::HKEY_USERS\$userSID\Software\Microsoft\Windows NT\CurrentVersion\Devices" ` -ErrorAction SilentlyContinue | Select-Object -Property * -ExcludeProperty PS* | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name $printerDevices = @( $allDevices | Where-Object { $d = $_ -not ($virtualPrinters | Where-Object { $d -like "*$_*" }) -and -not ($systemPrinters | Where-Object { $d -like "*$_*" }) } ) if ($ShowConsole) { Write-Host ' Printer Devices:' -ForegroundColor Yellow if ($printerDevices) { $printerDevices | ForEach-Object { Write-Host " - $_" -ForegroundColor White } } else { Write-Host ' None' -ForegroundColor Gray } } $results.Add([PSCustomObject]@{ ComputerName = $computerName Username = $username NetworkPrinters = if ($networkPrinters) { $networkPrinters -join '; ' } else { 'None' } DefaultPrinter = $defaultPrinterName PrinterDevices = if ($printerDevices) { $printerDevices -join '; ' } else { 'None' } PrinterCount = $networkPrinters.Count + $printerDevices.Count LastProfileUpdate = (Get-Item $profilePath -ErrorAction SilentlyContinue).LastWriteTime CollectionTime = $collectionTime Status = 'Success' }) } catch { if ($ShowConsole) { Write-Host " Error processing $username : $_" -ForegroundColor Red } $results.Add([PSCustomObject]@{ ComputerName = $computerName Username = $username NetworkPrinters = 'Error' DefaultPrinter = 'Error' PrinterDevices = 'Error' PrinterCount = 0 LastProfileUpdate = (Get-Item $profilePath -ErrorAction SilentlyContinue).LastWriteTime CollectionTime = $collectionTime Error = $_.Exception.Message Status = 'Failed' }) } finally { if ($hiveLoaded) { [System.GC]::Collect() Start-Sleep -Seconds 1 $null = reg unload "HKU\$userSID" } } } return $results } foreach ($computer in $ComputerName) { try { Write-Verbose "Targeting computer: $computer" $showConsole = -not $TableOutput.IsPresent if ($computer -eq $env:COMPUTERNAME) { & $scriptBlock $showConsole } else { $invokeParams = @{ ComputerName = $computer ScriptBlock = $scriptBlock ArgumentList = $showConsole ErrorAction = 'Stop' } if ($Credential) { $invokeParams['Credential'] = $Credential } Invoke-Command @invokeParams } } catch { Write-Error -Message "Failed to connect to '$computer': $($_.Exception.Message)" -ErrorAction Continue [PSCustomObject]@{ ComputerName = $computer Username = 'Connection Error' NetworkPrinters = 'Connection Failed' DefaultPrinter = 'Connection Failed' PrinterDevices = 'Connection Failed' PrinterCount = 0 CollectionTime = (Get-Date).ToString('dd-MM-yyyy HH:mm:ss') Error = $_.Exception.Message Status = 'Failed' } } } } } |