# Apply-ShopdbDefaultPrinter.ps1 # # Sets the logged-on user's default printer to the one ShopDB assigned. Runs IN # THE USER'S CONTEXT, at logon and on a repeat, because a default printer is # per-user state that SYSTEM cannot set for somebody else. # # Set-ShopdbPrinters.ps1 records the desired queue in # HKLM:\SOFTWARE\GE\ShopDB DefaultPrinter during the enforcement cycle. This # reads it. Splitting the two is not tidiness: the machine half needs SYSTEM and # the share, the user half needs a user - no single process has both. # # IT ALSO TURNS OFF "Let Windows manage my default printer". Leaving it on means # Windows silently overwrites the choice the next time somebody prints to another # queue, and the bay drifts back with nothing in any log to say why. # # Converges: when the current default already matches, it does nothing, so a # repeating trigger costs a registry read. A user who deliberately picks another # default WILL be corrected on the next run - that is the intent for a shared # bay. For a PC where that is wrong, schedule it at logon only. # # Exits 0 always. param( # Override for testing. Normally read from the machine hive. [string]$PrinterName = '' ) $ErrorActionPreference = 'Continue' $logDir = "$env:LOCALAPPDATA\ShopDB" if (-not (Test-Path $logDir)) { New-Item -ItemType Directory -Path $logDir -Force -ErrorAction SilentlyContinue | Out-Null } $logFile = Join-Path $logDir 'default-printer.log' function Log([string]$msg) { $ts = Get-Date -Format 'yyyy-MM-dd HH:mm:ss' "$ts $msg" | Tee-Object -FilePath $logFile -Append | Out-Null } if (-not $PrinterName) { foreach ($path in @('HKLM:\SOFTWARE\GE\ShopDB', 'HKLM:\SOFTWARE\WOW6432Node\GE\ShopDB')) { try { if (Test-Path $path) { $value = [string](Get-ItemProperty -Path $path -Name DefaultPrinter -ErrorAction Stop).DefaultPrinter if ($value -and $value.Trim()) { $PrinterName = $value.Trim(); break } } } catch {} } } if (-not $PrinterName) { # No default assigned is a legitimate state - a bay with three printers and # no favourite - so leave whatever the user has. Log 'no default assigned in ShopDB; leaving the current one alone' exit 0 } # Windows 10+ overrides any default the moment the user prints elsewhere, unless # this is off. Setting the default without clearing this is a fix that undoes # itself within a day. try { $windowsKey = 'HKCU:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows' $managed = (Get-ItemProperty -Path $windowsKey -Name LegacyDefaultPrinterMode -ErrorAction SilentlyContinue).LegacyDefaultPrinterMode if ($managed -ne 1) { Set-ItemProperty -Path $windowsKey -Name LegacyDefaultPrinterMode -Value 1 -Type DWord Log 'turned off "Let Windows manage my default printer"' } } catch { Log "WARN could not turn off Windows-managed defaults: $($_.Exception.Message)" } $queue = Get-Printer -Name $PrinterName -ErrorAction SilentlyContinue if (-not $queue) { # The enforcement cycle creates queues; this runs at logon and may simply be # earlier than the first cycle on a new bay. Next run picks it up. Log "assigned default '$PrinterName' is not installed yet; nothing to do" exit 0 } $current = (Get-CimInstance -ClassName Win32_Printer -Filter 'Default = True' -ErrorAction SilentlyContinue).Name if ($current -eq $PrinterName) { Log "already default: $PrinterName" exit 0 } try { $target = Get-CimInstance -ClassName Win32_Printer -Filter ("Name = '{0}'" -f $PrinterName.Replace("'", "''")) -ErrorAction Stop Invoke-CimMethod -InputObject $target -MethodName SetDefaultPrinter -ErrorAction Stop | Out-Null Log "default set: $PrinterName (was '$current')" } catch { Log "ERROR setting the default to '$PrinterName': $($_.Exception.Message)" } exit 0