We're trying to retrieve all installed printers in bulk. For this we use the -AsJob
switch on the Get-Printer
CmdLet. This works fine when all ComputerNames
exist, but when there's one that doesn't exist an error is correctly thrown.
Example
$ComputerName = @('Computer1', 'NonExisting', 'Computer2')
$GetPrinterJobs = Foreach ($C in $ComputerName) {
Get-Printer -ComputerName $C -AsJob
}
$GetPrinterJobs | Wait-Job -EA Ignore | Receive-Job
This code will throw one error for the NonExisting
ComputerName. How is it possible to see that the error is actually coming from ComputerName NonExisting
?
Get-Printer : The spooler service is not reachable. Ensure the spooler service is running.
With the help below from @JosefZ this is solved as following:
$GetPrinterJobs = Foreach ($C in $ComputerName) {
$C
Get-Printer -ComputerName $C -AsJob
}
$null = Get-Job | Wait-Job -EA Ignore
$GetPrinterJobResults = for ( $i = 0; $i -lt $GetPrinterJobs.Count; $i += 2 ) {
$ReceiveParams = @{
ErrorVariable = 'JobError'
ErrorAction = 'SilentlyContinue'
}
$ReceivedJobResult = $GetPrinterJobs[$i + 1] | Receive-Job @ReceiveParams
[PSCustomObject]@{
ComputerName = $GetPrinterJobs[$i]
State = $GetPrinterJobs[$i + 1].State
Data = $ReceivedJobResult
Error = if ($JobError) {
$JobError
$JobError.ForEach( { $Error.Remove($_) })
}
}
}
$GetPrinterJobResults
Here is my old-school workaround:
$ComputerName = @('Computer1', 'NonExisting', 'Computer2')
$GetPrinterJobs = Foreach ($C in $ComputerName) {
$C
Get-Printer -ComputerName $C -AsJob
}
$GetPrinterJobResults = $GetPrinterJobs |
Where-Object { $_.GetType().Name -ne 'String'} |
Wait-Job -EA Ignore | Receive-Job
for ( $i = 0; $i -lt $GetPrinterJobs.Count; $i+=2 ) {
@{
$GetPrinterJobs[$i] = $GetPrinterJobs[$i + 1].State
}
}
Should return something like
Name Value
---- -----
Computer1 Completed
NonExisting Failed
Computer2 Completed