Win_Printers.PS1 - Hanging

CMK version: Checkmk Raw Edition 2.1.0p21
**OS version: Ubuntu Linux 22.04.2 **

Error message: None, nothing returned

Output of “cmk --debug -vvn hostname”: (If it is a problem with checks or plugins)

OK, so I’ve looked around and tried various things. I’ve been able to create this check on the demo version with a few printers on the print server, so I KNOW it will be useful.

On my ‘production’ intended RAW implementation of CHECKMK, which needs to gather data from Print Servers with 300+ printers on each, however, it fails to work.

It’s not the CHECKMK server though it is the Win_printers.PS1 agent which is hanging.

I’ve narrowed it down to the “Get-WmiObject win32_printer” command which is taking a LOOOONG time to run. If I do in PowerShell with out any qualifiers it fails/hangs after around… 200 printers … (estimate could be ± 5 from this).

It finally completes with a compete list of printers(395 printers).

As does the agent/script.

The command “Get-WMIObject Win32_PerfFormattedData_Spooler_PrintQueue” completes more or less instantly (the list from this matches the number from the other command).

  1. is there any REAL reason for the 2nd command (“Get-WmiObject win32_printer” ) in the script?
  2. is there a better command whcih could be used now (something CIM rather than WMI)?

Otherwise what can I do?



It would be interesting how long a “get-printer” takes on your big system.
The only reason for to use the “get-wmiobject win32_printer” is the error state.
This status is also not available inside the “get-printers” if i see it the right way.


We experience the same problems with printer queue monitoring and as far as we found out WMI is basically the root cause but also as you mentioned the script is not very efficient and could be improved. For any print server with +100 printer queues its no more usable. We didnt checked if there is a difference in performance between WMI and CIM. Until now we have no alternative for the WMI way.



What do you mean by ‘get-printers’?

Btw I don’t consider this a big system…

I worked out that the 2nd line was to gather the error state, and can see that this would be useful, however I am tempted to edit the check so it only checks no. of jobs in the queue… (But am concerned I’ll break the script…).

Which is a good indicator of error state anyway!


The powershell command “get-printer” does this also timeout on your system?

I will try that when I’m back at work on Monday…


Intriguingly Google has been spying on me and put this in my feed PowerShell guide to Get-CimInstance & Get-WmiObject | PDQ

Saying we should be using CIM (open source cross platform) instead of WMI (Windows only).

So I’m going to have a look at using CIM in the script instead…

Will feedback on Monday.


get-printer works as expected running almost instantly.

I should also point out that the other command does finish eventually… (in the same way that Manuel will forget… eventually).

Get-CIMInstance win32_printer

Also takes a significant amount of time to run (over 3 minutes - timing it properly now).

It comes back with the info:

Name ShareName SystemName PrinterState PrinterStatus Location

GetCimInstance Win_32Printer: Time taken to complete is 5:03, to show 397 printers.

Get-WmiObject win32_printer starts showing stuff immediately, pauses after 15 seconds, and seems to hang - gives data in a different format:

Location      :
Name          :
PrinterState  :
PrinterStatus :
ShareName     :
SystemName    :

Takes exactly the same time to run (5minutes 3 seconds)

So its the win_32printer bit that is taking the time.

So next step is to work out how to create the table without the ‘error state’ - which I can deduce from no. of prints in the queue anyway…

Any ideas?

Right, I THINK I know how to do this, removing the Data_Set2 completely, and sending just the Data_Set1 formatted as a table with empty columns for PrinterStatus, DetectedErrorState.

Interestingly there is a decent amount of granular data in the original Data_Set1, I have pulled out the following:

Name                          Jobs PrinterStatus DetectedErrorState JobErrors JobsSpooling MaxJobsSpooling TotalJobsPrinted TotalPagesPrinted
----                          ---- ------------- ------------------ --------- ------------ --------------- ---------------- -----------------
_Total                        1329                                         12            0             266            24731                 8
HP Universal Printing PCL 6      0                                          0            0               0                0                 0
Microsoft Print to PDF           0                                          0            0               0                0                 0
Microsoft XPS Document Writer    0                                          0            0               0                0                 0

Most all of which I’d like to record in CheckMK (if I am able to) - how do I get CheckMK to parse the additional data and do I need to fill the empty columns (PrinterStatus, and DetectedErrorState) with 0s/other content?


So, after some fiddling I’ve got it working in a way that is OK for me (for the moment). I’ve replaced the Get-WMIObject with Get-CIMIntance, and set the error states to 1 (which CMK reads as other).

Get-CIMInstance seems to run a little faster than the Get-WMIObject and should be portable across systems (and upgrades to PowerShell - I think you could use this running on linux version of PowerShell on the CheckMK server to do the checks remotely).

I include my version of the win_printers.ps1 script/plugin…
win_printers.ps1 (2.7 KB)

In case it is useful for anyone.

1 Like

Thank you, we will definitely test this and if it works well l I will request to change this in the official code.

As an addendum you can use the GetCIMInstance Win32_Printers with a list of computer names to create a table across multiple print servers - if this could be specified in the web interface as parameters to pass through, OR include a section in the script, OR have a config file for the script (default being localhost), this could also be useful…
(the code would look something like this:

$s = New-CimSession -ComputerName Server1, Server2, Server3
Get-CIMInstance Win32_PerfFormattedData_Spooler_PrintQueue -CimSession $s| Select Name, Jobs, JobErrors, JobsSpooling, MaxJobsSpooling, TotalJobsPrinted, TotalPagesPrinted  | Sort Name | format-table

Now, given CIM can run in LINUX powershell you could do the check remotely on the CheckMK server, to get the stats…

Except MS haven’t written CimCmdlets for Linux powershell, this :“This module is only available on the Windows platform” from CimCmdlets Module - PowerShell | Microsoft Learn :melting_face: :unamused: