PowerShell Tutorial – How to Keep Tabs on XenApp Printer Queues

Sam Jacobs posted a great PowerShell script and tutorial on IPM’s corporate blog that I wanted to share with everyone.

A few weeks ago, a client of ours began noticing that printer queues on certain XenApp servers were experiencing errors, and jobs sent to those queues were left stranded and never printed. As it turned out, the problem was caused by an updated printer driver, and the issue only occurred when that printer driver was used.

Since there were quite a few servers involved, with 10-20 print queues per server, it seemed like a job for a WMI script. The first version (a .VBS script) looked something like this:

strServer = "."
strQuery = "SELECT * FROM Win32_PerfFormattedData_Spooler_PrintQueue "

objWMIService = GetObject (“winmgmts:\” & strServer & “rootCIMV2″)
Set colItems = objWMIService.ExecQuery (strQuery)

Wscript.Echo “Printer” & vbTab & “Jobs” & vbTab & “JobErrors”
For Each objItem In colItems
WScript.Echo objItem.Name & vbTab & objItem.Jobs & vbTab & objItem.JobErrors

objWMIService = Nothing
Set colItems = Nothing

While the above worked just fine, due to the varying length printer names, the resultant output was a bit difficult to read. Here’s what the output looked like when run on my local machine:

PowerShell to the rescue! In order to get the same output, only a single line is needed to get the same results in PowerShell (while wrapped here for readability, it may all be placed on a single line):

Get-WMIObject Win32_PerfFormattedData_Spooler_PrintQueue -computerName . |
Select Name, Jobs, JobErrors | ft –auto

The command above uses the Get-WMIObject cmdlet to read the print queues of the current server, pipes the output to select the desired fields: Name (printer name), Jobs (Number of Pending Jobs), and JobErrors (Number of Errors), and pipes the output to the Format-Table cmdlet (alias: ft) to automatically give us a nicely formatted table:

Much easier to read!

Now let’s add two additional features. First of all, we need to be able to cycle through the print queues of all our XenApp servers. While this could be done by importing the Active Directory PowerShell module and using some AD cmdlets, it’s pretty easy to just create a file with the names of the XenApp servers. This way, we don’t need to add any additional software to the XA servers.

Since we’re only interested in printers that have errors, it would also be nice to highlight only those printers which have jobs pending (signaling a possible problem).

Here is the PowerShell script with the above features added:

$servers = Get-Content 'CitrixServerList.txt'  
ForEach ($server in $servers) {
try {
write-host "Processing printers for: " $server " ..."
Get-WMIObject Win32_PerfFormattedData_Spooler_PrintQueue
-computerName $server -ea stop |
?{$_.jobs -gt 0} |
Select @{Expression={$_.Name};Label=$server+" printers"},
Jobs, JobErrors |
ft -auto
} catch [System.Exception] {
write-host $server "...cannot retrieve printer names"

First, we retrieve the list of XenApp servers (with one server per line in the text file).

We then cycle through each server, wrapping the code in a try/catch block to handle errors (in case one of the servers is offline, for example).

The new parts of the script above:

-computerName  $server    the XenApp server name from the ForEach command
-ea stop set the ErrorAction (ea) to stop processing the command if an error occurs
?{$_.jobs -gt 0} only show printer queues with jobs pending

The term @{Expression={$_.Name};Label=$server+” printers”} shows how to rename column headings in the output.

Output of the final version above: