I am teaching myself some powershell and as a side project, I wrote a script that will ping and monitor printers that are in my active directory. The script is working fine. but is displaying "ONLINE: " $someprinterName
I want to create a table with three columns: PrinterName, Status (online or offline).
I have written the rest of the code, but I can not figure out how to put it into table format with such two columns. I tried to put it in an array and then use: $something | Format-Table -Property .... but nothing worked for me. I am sorry, I know this is too simple, but all sources I looked into did not help me much.
code is below:
$printers = Get-AdObject -filter "objectCategory -eq 'printqueue'" -Properties * | Select-Object -Property *
$array = @()
Function Select-Printer {
foreach ($printer in $printers)
{
[array]$printerArray = $printer.portName
}
return $printerarray
}
#Start Processing
$newline = "`r`n"
Do {
$downcount = 0
$down=$Null
#Write-Host (Get-Date)
$hostlist = Select-Printer
ForEach ($hostname in $hostlist) {
if ($hostname.length -gt 0) {
$hoststatus = Test-Connection -ComputerName $hostname -Count 1 -ea silentlycontinue
#$array = $hostname
$array = $hoststatus
if($hoststatus) {
write-host "Online: "$hostname -BackgroundColor DarkGreen -ForegroundColor White
} else {
write-host "OFFLINE: "$hostname -BackgroundColor DarkRed -ForegroundColor White
$downcount = $downcount 1
[array]$down = $hostname
}
}
}
Write-Host "Down Hosts:"$downcount
Write-host -NoNewline "Pausing "
for ($s=0;$s -le 6; $s ) {
Write-Host -NoNewline "."
Start-Sleep 5
}
Write-Host ""
}
while ($true)
CodePudding user response:
First thing to notice is that using =
to add elements to an array is very costly, because the entire array has to be rebuilt in memory on each addition.
Next, you should not ask for all properties of an object when you only just need one (in this case portName
)
The function you have is not needed, as you can get an array of portnames in just one go.
# get an array of printer portnames and remove empty or whitespace only elements
$printers = (Get-AdObject -Filter "objectCategory -eq 'printqueue'" -Properties portName).portName | Where-Object {$_ -match '\S'}
$downcount = 0
# loop through the portnames and test if they are online or not
$result = foreach ($hostname in $printers) {
# if you specify the Quiet parameter, it returns a Boolean value.
$hoststatus = Test-Connection -ComputerName $hostname -Count 1 -Quiet -ErrorAction SilentlyContinue
[PsCustomObject]@{
PrinterPortName = $hostname
Status = if ($hoststatus) { 'Online' } else { 'Offline' }
}
if (!$hoststatus) { $downcount }
}
# the `@()` makes sure $result is treated as array, so we can use its .Count property
# the surrounding `$()` subexpression resolves the value inside the string
Write-Host "Tested $(@($result).Count) printers; Down Hosts: $downcount"
# now show the result as table on screen
$result | Format-Table -AutoSize
# and save as CSV file for later use perhaps?
$result | Export-Csv -Path 'X:\Somewhere\printers.csv' -NoTypeInformation
As per your comment to be able to set the background color in the console printout, you can do this:
$table = $result | Format-Table -AutoSize | Out-String -Stream
# next loop through these lines and find lines that match 'Offline'
switch -Regex ($table) {
'Offline' { Write-Host $_ -BackgroundColor Red }
default { $_ } # all other lines go in the default color
}
The output will now look like