The following workflow generates a list of all the printers on a server:
Workflow Get-PrintersInstalledHC {
Param (
[String[]]$Servers
)
Foreach -Parallel ($S in $Servers) {
InlineScript {
$S = $Using:S
Write-Verbose "Server: $S"
Try {
if ($Printers = Get-Printer -ComputerName $S -Full -EA Stop) {
$Params = @{
ComputerName = $S
Property = '*'
ErrorAction = 'Stop'
}
$Config = Get-CimInstance @Params -ClassName Win32_PrinterConfiguration
$Ports = Get-CimInstance @Params -ClassName Win32_TCPIPPrinterPort
Foreach ($P in $Printers) {
Write-Verbose "Printer: $($P.Name)"
Foreach($C in $Config) {
if ($P.Name -eq $C.Name) {
$PortHostAddress = $Ports | Where {$_.Name -eq $P.PortName} |
Select -ExpandProperty HostAddress
$Prop = @{
PortHostAddress = $PortHostAddress
DriverVersion = $C.DriverVersion
Collate = $C.Collate
Color = $C.Color
Copies = $C.Copies
Duplex = $C.Duplex
PaperSize = $C.PaperSize
Orientation = $C.Orientation
PrintQuality = $C.PrintQuality
MediaType = $C.MediaType
DitherType = $C.DitherType
RetrievalDate = (Get-Date -Format 'dd/MM/yyyy HH:mm')
}
$P | Add-Member -NotePropertyMembers $Prop -TypeName NoteProperty
Break
}
}
}
[PSCustomObject]@{
ComputerName = $S
ComputerStatus = 'Ok'
RetrievalDate = (Get-Date -Format 'dd/MM/yyyy HH:mm')
Printers = $Printers
}
}
}
Catch {
if (Test-Connection $S -Count 2 -EA Ignore) {
[PSCustomObject]@{
ComputerName = $S
ComputerStatus = "ERROR: $($Error[0].Exception.Message)"
RetrievalDate = (Get-Date -Format 'dd/MM/yyyy HH:mm')
Printers = $null
}
}
else {
[PSCustomObject]@{
ComputerName = $S
ComputerStatus = 'Offline'
RetrievalDate = (Get-Date -Format 'dd/MM/yyyy HH:mm')
Printers = $null
}
}
}
}
}
}
$Printers = Get-PrintersInstalledHC Server1
What I am having trouble with is filtering out the empty values in $Printers.Printers.PortHostAddress. As discussed here it should suffice to just do:
$Printers.Printers.PortHostAddress | where {$_} | % -Begin{$i = 0} -Process{$i; $_; $i++}
Other attempts are not working either, as:
$Printers.Printers.PortHostAddress | where {$_ -ne $null} | % -Begin{$i = 0} -Process{$i; $_; $i++}
$Printers.Printers.PortHostAddress | where {$_ -ne ''} | % -Begin{$i = 0} -Process{$i; $_; $i++}
Unfortunately, when the printer's name is for example Microsoft XPS Document Writer and the value in PortHostAddress stays empty, it's still not filtered out of the list as you can see by the numbers.
Is there another way to filter out the PortHostAddress when there is no value?
$Null. Fixed it with a workaround in theWorkflowby changing it toPortHostAddress = if ($PortHostAddress) {$PortHostAddress} else {$null}. Don't know if this is the clean way to do it, but it works.System.Management.Automation.PSCustomObject. That is why your check in comments is working and null is not.($_ -as [string]) -ne ''?