Correct a drifted print queue instead of leaving it wrong
A queue was matched by NAME alone, so a bay whose printer had moved, or whose queue was built on a driver the site has since replaced, looked converged and printed to the wrong device. Absence was fixed; drift was not. Set-ShopdbPrinters.ps1 now repoints a queue whose port does not match the address ShopDB holds, and swaps a queue built on the wrong driver. Both are things ShopDB is authoritative about: where the printer IS, and what drives it. CORRECTED IN PLACE with Set-Printer, never removed and recreated. The queue keeps its name, its sharing, its permissions, and whoever has it as their default keeps it - which is what makes this safe to run every cycle on a live floor. There is still no removal code path in this script at all. Two guards, because a repair that breaks a working printer is worse than drift: the driver is only swapped when the wanted one is actually staged, and -WhatIfOnly reports both kinds of correction without making either. Verified on Windows against a queue that had the right name, the wrong port, the wrong driver AND was the logged-on user's default: both fields were corrected and the queue was still the default afterwards. The earlier no-op guarantees were re-run and still hold - nothing assigned changes nothing, and an assignment with no default leaves the user's own default alone.
This commit is contained in:
@@ -93,6 +93,61 @@ if ($wanted.Count -eq 0) {
|
||||
}
|
||||
Log "assigned: $($wanted.Count) printer(s)"
|
||||
|
||||
function Ensure-Port([string]$address) {
|
||||
$portname = 'IP_' + $address
|
||||
if (-not (Get-PrinterPort -Name $portname -ErrorAction SilentlyContinue)) {
|
||||
Add-PrinterPort -Name $portname -PrinterHostAddress $address -ErrorAction Stop
|
||||
Log "port: $portname"
|
||||
}
|
||||
return $portname
|
||||
}
|
||||
|
||||
function Repair-Queue($queue, [string]$address, [string]$drivername) {
|
||||
$name = $queue.Name
|
||||
|
||||
# The address ShopDB holds is the truth about where the printer IS. A queue
|
||||
# left pointing at the old address prints into the void, and looks fine.
|
||||
if ($address) {
|
||||
$wantedport = 'IP_' + $address
|
||||
if ($queue.PortName -ne $wantedport) {
|
||||
if ($WhatIfOnly) {
|
||||
Log "WOULD repoint $name : $($queue.PortName) -> $wantedport"
|
||||
} else {
|
||||
try {
|
||||
$portname = Ensure-Port $address
|
||||
Set-Printer -Name $name -PortName $portname -ErrorAction Stop
|
||||
Log "repointed $name : $($queue.PortName) -> $portname"
|
||||
} catch {
|
||||
Log "ERROR repointing ${name}: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# A queue built on a driver the site has moved off keeps using it forever.
|
||||
# Only corrected when the wanted driver is actually staged - swapping a queue
|
||||
# onto a driver that is not installed would break a working printer.
|
||||
if ($drivername -and $queue.DriverName -ne $drivername) {
|
||||
if (-not (Get-PrinterDriver -Name $drivername -ErrorAction SilentlyContinue)) {
|
||||
Log "SKIP driver fix for $name : '$drivername' is not staged"
|
||||
} elseif ($WhatIfOnly) {
|
||||
Log "WOULD re-driver $name : $($queue.DriverName) -> $drivername"
|
||||
} else {
|
||||
try {
|
||||
Set-Printer -Name $name -DriverName $drivername -ErrorAction Stop
|
||||
Log "re-drivered $name : $($queue.DriverName) -> $drivername"
|
||||
} catch {
|
||||
Log "ERROR re-drivering ${name}: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($queue.PortName -eq ('IP_' + $address) -and
|
||||
($drivername -eq '' -or $queue.DriverName -eq $drivername)) {
|
||||
Log "present: $name"
|
||||
}
|
||||
}
|
||||
|
||||
$existing = @{}
|
||||
foreach ($queue in (Get-Printer -ErrorAction SilentlyContinue)) {
|
||||
$existing[$queue.Name] = $queue
|
||||
@@ -104,19 +159,28 @@ foreach ($printer in $wanted) {
|
||||
if (-not $name) { continue }
|
||||
if ($printer.printerid -eq $defaultid) { $defaultname = $name }
|
||||
|
||||
$address = $printer.hostname
|
||||
if (-not $address) { $address = $printer.ipaddress }
|
||||
$drivername = $printer.drivername
|
||||
|
||||
if ($existing.ContainsKey($name)) {
|
||||
Log "present: $name"
|
||||
# A queue with the right NAME can still be wrong: pointing at a printer
|
||||
# that has moved, or built on a driver that has since been replaced.
|
||||
# Absence used to be the only thing fixed, so a bay with a stale queue
|
||||
# looked converged and printed to the wrong device.
|
||||
#
|
||||
# Corrected IN PLACE with Set-Printer, never removed and recreated: the
|
||||
# queue keeps its name, its sharing, its permissions, and whoever has it
|
||||
# as their default keeps it.
|
||||
Repair-Queue $existing[$name] $address $drivername
|
||||
continue
|
||||
}
|
||||
|
||||
$address = $printer.hostname
|
||||
if (-not $address) { $address = $printer.ipaddress }
|
||||
if (-not $address) {
|
||||
Log "SKIP $name : no hostname or IP to point a port at"
|
||||
continue
|
||||
}
|
||||
|
||||
$drivername = $printer.drivername
|
||||
if (-not $drivername) {
|
||||
Log "SKIP $name : ShopDB has no driver name for it"
|
||||
continue
|
||||
@@ -132,12 +196,8 @@ foreach ($printer in $wanted) {
|
||||
continue
|
||||
}
|
||||
|
||||
$portname = 'IP_' + $address
|
||||
try {
|
||||
if (-not (Get-PrinterPort -Name $portname -ErrorAction SilentlyContinue)) {
|
||||
Add-PrinterPort -Name $portname -PrinterHostAddress $address -ErrorAction Stop
|
||||
Log "port: $portname"
|
||||
}
|
||||
$portname = Ensure-Port $address
|
||||
Add-Printer -Name $name -DriverName $drivername -PortName $portname -ErrorAction Stop
|
||||
Log "created: $name -> $address ($drivername)"
|
||||
} catch {
|
||||
|
||||
Reference in New Issue
Block a user