Ein typisches Problem in der Windows Printserver Welt scheinen fehlerhafte (=hängende) Druckeraufträge zu sein.
Wenn ein Druckauftrag fehlerhaft ist, blockiert er diesen Drucker, bis dieser Druckauftrag entfernt wurde.
Damit blockierte Drucker nicht durch die BenutzerInnen gemeldet werden müssen (immer unschön und wenig professionell), habe ich einen Check in VBSkript für Nagios/NSclient geschrieben, welcher alle registrierten Drucker mittels WMI auf eben diese Aufträge prüft:
Dieses Skript sollte über einen Windows-Server z.B. über NRPE (mit NSCLIENT++) aufgerufen werden und nimmt als Argument den Computernamen an.
Dazu nimmt man folgende Einstellungen im NSClient vor (gilt für Version 0.38):
Im Nagios muss dann folgendes in die commands.cfg eingetragen werden:
Entweder die Verteilung des Service über einen Host oder eine Hostgruppe (Argument wäre der "Hop"-Server):
define command {
command_name check_windows_print_spooler
command_line $USER1$/check_nrpe -H $ARG1$ -c check_print_spooler -a $HOSTADDRESS$
}
Oder als rein lokale Variante:
define command {
command_name check_windows_print_spooler
command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_print_spooler -a "."
}
Folgende Dinge werde ich wohl noch implementieren:
* UPDATE: Damit das Skript besser skaliert, habe ich den Code etwas umgebaut und ein Flag eingebaut, welches den fehlerhaften Job automatisch löscht.
Download: https://dl.dropboxusercontent.com/u/9482545/check_print_spooler.vbs
Wenn ein Druckauftrag fehlerhaft ist, blockiert er diesen Drucker, bis dieser Druckauftrag entfernt wurde.
Damit blockierte Drucker nicht durch die BenutzerInnen gemeldet werden müssen (immer unschön und wenig professionell), habe ich einen Check in VBSkript für Nagios/NSclient geschrieben, welcher alle registrierten Drucker mittels WMI auf eben diese Aufträge prüft:
' MSDN: http://msdn.microsoft.com/en-us/library/aa394370%28v=vs.85%29.aspx ' Required Variables ' Author: Oliver Skibbe oliskibbe (at) gmail.com ' Date: 2013-10-30 Const PROGNAME = "check_print_spooler" Const VERSION = "1.1.0" ' Nagios helper functions Include "C:\Programme\NSClient++\scripts\lib\NagiosPlugins.vbs" ' Arguments strComputer = WScript.Arguments.Item(0) ' Defaults return_code = 0 return_msg = "Everythings fine" ' automatically kill job? killjob = true ' Create WMI object Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") ' Create the NagiosPlugin object Set np = New NagiosPlugin ' Fetch all jobs with status error Set Result = objWMIService.ExecQuery("Select * From Win32_PrintJob Where Status = 'Error'") For Each instance In Result ' automatic job kill If killjob = True Then instance.Delete_ Else ' JobId is attached to "caption, description and name" thus we want to split and accessible with printerName(1) printerName = Split(instance.Caption,",") ' if job should not be automatically killed, print critical and printer name failedPrinterStr = failedPrinterStr & " " & Chr(34) & printerName(0) & Chr(34) return_code = 2 End If next If return_code > 0 Then return_msg = "Job Errors on printer " & failedPrinterStr End If ' Nice Exit with msg and exitcode np.nagios_exit return_msg, return_code Sub Include( cNameScript ) Set oFS = CreateObject("Scripting.FileSystemObject") Set oFile = oFS.OpenTextFile( cNameScript ) ExecuteGlobal oFile.ReadAll() oFile.Close End Sub
Dieses Skript sollte über einen Windows-Server z.B. über NRPE (mit NSCLIENT++) aufgerufen werden und nimmt als Argument den Computernamen an.
Dazu nimmt man folgende Einstellungen im NSClient vor (gilt für Version 0.38):
; Script to check external scripts and/or internal aliases. CheckExternalScripts.dll
[NRPE] ;# NRPE PORT NUMBER ; This is the port the NRPEListener.dll will listen to. port=5666 ;# COMMAND TIMEOUT ; This specifies the maximum number of seconds that the NRPE daemon will allow plug-ins to finish executing before killing them off. command_timeout=60 ;# COMMAND ARGUMENT PROCESSING ; This option determines whether or not the NRPE daemon will allow clients to specify arguments to commands that are executed. allow_arguments=1 [External Scripts] check_print_spooler=cscript.exe //T:30 //NoLogo scripts\check_print_spooler.vbs $ARG1$Der aufmerksame Leser wird festgestellt haben, dass dem Spooler ein Argument übergeben werden kann, dieses nimmt den Namen des Servers an, das heißt man kann von einem Server aus viele andere Server angesprochen werden können, dazu muss dann allerdings der NSClient++ Dienst mit einem entsprechenden User gestartet werden, für den rein lokalen Aufruf ("." oder "localhost") reicht das Systemkonto.
Im Nagios muss dann folgendes in die commands.cfg eingetragen werden:
Entweder die Verteilung des Service über einen Host oder eine Hostgruppe (Argument wäre der "Hop"-Server):
define command {
command_name check_windows_print_spooler
command_line $USER1$/check_nrpe -H $ARG1$ -c check_print_spooler -a $HOSTADDRESS$
}
Oder als rein lokale Variante:
define command {
command_name check_windows_print_spooler
command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_print_spooler -a "."
}
Folgende Dinge werde ich wohl noch implementieren:
- Flag für automatisches Löschen der Jobs
- E-Mail an Druckjobersteller, dass der Job abgebrochen wurde
- Umbau auf PHP mit Nutzung von "wmic", d.h. Hop-Server wird überflüssig
* UPDATE: Damit das Skript besser skaliert, habe ich den Code etwas umgebaut und ein Flag eingebaut, welches den fehlerhaften Job automatisch löscht.
Download: https://dl.dropboxusercontent.com/u/9482545/check_print_spooler.vbs
in der nsc muss noch ein komma weg:
AntwortenLöschen; Script to check external scripts and/or internal aliases.
CheckExternalScripts.dll
1) In der NSC muss das komma vor "CheckExternalScripts.dll" noch weg
AntwortenLöschen2) Die argument-weitergabe funktionierte ums verrecken nicht.
Da ich aber eh nur die lokale variante wollte habe ich in deinem script
' Arguments
'strComputer = WScript.Arguments.Item(0)
auskommentiert und einfach
' Create WMI object
Set objWMIService = GetObject("winmgmts:\\localhost\root\cimv2")
hergenommen.
Dann kann in der nagios commands.cfg
das -a "." am Ende weggelassen werden und es funktioniert :-)
Current Status:
OK
(for 0d 0h 8m 34s)
Status Information: OK: Everythings fine
Klingt gut, vielen Dank für die Hinweise :-)
AntwortenLöschenAlternativ kann die Zeile:
'strComputer = WScript.Arguments.Item(0)
auch gegen
'strComputer = "."
getauscht werden.
Den Hinweis mit der CheckExternalScripts DLL habe ich noch eingebaut.