PRTG Pause

Ich überwache per PRTG meine Server aber wenn ich einen Server boote, dann sollte man vorher den Server im Monitoring auf "Pause" oder auf "Meldungen unterdrücken" für eine einstellbare Zeit stellen. Ebenso würde ich mir wünschen, dass ich auf dem Server selbst auch den Status einsehen kann, den PRTG glaubt zu wissen. bei SCOM gab es ja ein Programm um einen Server für eine bestimmte Zeit im Monitoring zu pausieren. Das fehlt mir für PRTG.

Recherche

Ich bin erst mal davon ausgegangen, dass diese Aufgabenstellung nicht neu ist. Nicht jeder "Operator", der einen Server verwaltet darf auch in PRTG Änderungen vornehmen. Also habe ich erst mal gesucht, ob es nicht schon etwas gibt und in der Knowledgebase gab es schon einige Treffer, z.B.:

PRObject.exe

Ich habe einen Hinweis auf das Programm "PRObject.exe" gefunden, welches folgende Parameter unterstützt:

-u=    The URL of your PRTG installation.
-un=   PRTG Username.
-pw=   PRTG Password or PassHash *.
-id=   The ObjectID you want to pause, resume, or check now.
-a=    The action to perform (p für pause, r für resume, c für checknow).
-s     Optional switch to suppress the textual output
PRObject -u=yourPRTGServer -un=myUser -pw=mypassword -id=1001 -a=p

Damit wäre es schon einmal möglich einen Server per Kommandozeile zu "pausieren". Ein erster Schritt zu einem Icon im Startmenü, welcher das Monitoring geplant unterbrechen kann. Aber wie bitte soll ich hier "sicher" einen Benutzernamen und Kennworthash hinterlegen. Weiterhin muss die Applikation ja die Object-ID wissen. Das ist wohl nicht zu Ende gedacht worden.

Überlegungen und Wunsch

Eigentlich sollte es ein Windowsprogramm geben, welches per AutoStart auf dem PC als Tray-Applikation immer gleich mit gestartet werden kann und vom PRTG-Server den aktuellen Status dieses Servers abfragt. Das kann eine Art farbige Ampel im Tray sein, ein Popup oder wegen mir auch eine Ausgabe als Bildschirmhintergrund (a la BGINFO). Am liebsten aber wirklich eine normale Windows Form Applikation die einen "ServerView" vom PRTG-Server abholt. Über ein Kontextmenü könnte man die Überwachung vielleicht auch Pausieren und Fortsetzen.

Natürlich muss eine pfiffige Lösung zur Konfiguration gefunden werden, damit diese Applikation auch den PRTG-Server findet, vor allem wenn auf dem System gar keine lokale Probe installiert ist und der Server nur "remote" überwacht wird. Denkbar wären hier die klassischen Gruppenrichtlinien oder vielleicht auch DNS Service Record oder LDAP-Einträge. Wenn der PRTG-Server im gleichen Forest ist, könnte er ja einen Service Connection Point im Active Directory veröffentlichen. Exchange macht die auch so, damit Outlook intern "Autodiscover"-Server findet.

Bleibt die Frage der Authentifizierung. Alle verteilten Programme mit einem generischen Account zu betreiben ist mir zu heikel, zumal das Konto dann sicher zu viele Berechtigungen hätte. Es könnte ja "alle Server auf Pause" setzen. Ein abschreckender Gedanke.

Aber jeder Server hat ja eine IP-Adresse und könnte die HTTP/HTTPS-URL des PRTG-Servers erreichen. IP-Adressen können bei UDP recht einfach gefälscht werden aber bei TCP-Verbindungen ist der Aufwand schon viel höher (z.B. ARP-Spoofing etc.). Aktuell erlaubt PRTG aber noch keine "Authentifizierung" per SourceIP um über die HTTP-API an Daten zu kommen und Aktionen auszulösen. Das wäre aus meiner Sicht eine fast optimale Lösung, die aber nur der Hersteller von PRTG selbst einbauen kann.

Übergangslösung

Aber über die HTTP-API ist es sehr einfach, mit einem Benutzernamen und Kennwort (oder Hash) diese Funktionen auszuführen und so habe ich als "Proof of Concept" mir ein PowerShell-Skript gebaut, welches auf der einen Seite per HTTPListener auf Anfragen von Clients wartet und ausgehend von der Source-IP mit PRTG als Backend kommuniziert.

Das PowerShell-Script starte ich Anfang einfach interaktiv auf dem PRTG-Server und lasse es auf einem anderen Port lauschen.. Es kann aber natürlich auch auf einem anderen Server laufen. PowerShell-Skripte lassen sich auch als Task planen (Siehe PS Beispiele:PowerShell im Dauereinsatz (Taskplaner)), damit sie im Hintergrund laufen.

Achtung: Das Skript muss als Administrator laufen, da das Skript ansonsten den HTTP-Listener nicht selbst erstellen kann. Auf PS HTTPServer finden Sie eine Beschreibung, wie Sie als Admin den Listener erstellen, damit das Skript auch ohne administrative Rechte laufen kann.

Das Dienstkonto, mit dem der Zugriff auf die PRTG-Instanz erfolgt kann nur die Sensoren sehen und pausieren, auf die es in PRTG auch Rechte hat. Er sollte also zumindest "READ" Auf der Root über eine Gruppe bekommen und die Sensoren, die pausiert werden sollen, auch schreiben können.

Windows Firewall
Sie müssen zudem auch noch den Port in der Windows Firewall öffnen.

Im Skript müssen natürlich ein paar Parameter hinterlegt werden:

param (
           [string]$prtgserveruri="http://localhost:80", # URL of PRTG Web Server
           [string]$prtgUsername="prtgadmin",              # Username
           [string]$prtgpasshash="12345678" ,              # hash instead of password
           [string]$listenport = "81"                      # Port to accept connections
)

Der Benutzer muss natürlich zum einen alle Geräte sehen können und wenn Sie auch die Funktion "Pause/Resume" nutzen, dann braucht er auf jeden Fall auch Schreibrechte. Leider gibt es in PRTG keine Möglichkeit das Recht zum "Pause" gesondert zu vergeben.

Sie können die Parameter im Skript anpassen oder beim Aufruf übergeben.

Das Ablegen von Anmeldedaten in einem Skript ist immer kritisch zu betrachten, da damit auch eine direkte Anmeldung an PRTG möglich ist. Sichern Sie daher das Skript und legen Sie am besten einen eigenen Benutzer für diese Gateway-Funktion an.

Das Skript durchläuft dann folgende Schritte:

  • Kontrolle, ob der PRTG-Server mit den angegebenen Daten erreichbar ist
    Dazu wird einfach der PRTG-Status innerhalb einer Try/Catch-Anweisung abgerufen und im Fehlerfall abgebrochen
[xml]$data=Invoke-WebRequest -Uri ($prtgserveruri+"/api/getstatus.xml?id=0&Username="
               +$prtgUsername+"&passhash="+$prtgpasshash)
write-host ("PRTG-Version:"+ $data.status.Version)
write-host ("PRTG-Clock  :"+ $data.status.Clock)
  • Auf Anfragen warten
    Dann wird der Listener initialisiert und eingehende HTTP-Anfragen erwartet. für jede Anfrage wird dann folgendes durchgeführt
    • Laden/Aktualisieren der DeviceListe
      Dazu wird wieder die API bemüht, um die Liste der Geräte zu ermitteln. Wenn der Host keine IP-Adresse ist, wird noch eine Namensauflösung eingeschaltet. Als Ergebnis habe ich eine Hashtabelle mit den IP-Adressen der überwachten Geräte und der dazugehörigen PRTG-ID
[xml]$data= Invoke-WebRequest -Uri ($prtgserveruri 
      +"/api/table.xml?content=devices&output=xml&columns=device,host,objid&Username="
      +$prtgUsername+"&passhash="+$prtgpasshash)
    • Laden des HTML-Template
      Das ist eine Rumpfseite, in der einige Ersetzungsstellen mit %VARNAME% und die Styles hinterlegt sind. Auf Bilder habe ich verzichtet, da das Skript kein kompletter Webserver ist. Wenn Sie Bilder verwenden wollen, sollten Sie diese von einem anderen Server beziehen.
    • Suche der anfragenden IP und Generierung der Ausgabe
      Wird die IP-Adresse in der Liste gefunden, dann werden der Status zu dem Gerät, die Sensoren darunter und die letzten 10 Meldungen per HTTP-API ermitteln und an den Client zurück gesendet.
      Abhängig vom Status werden noch URLs für ein "Pause" und ein "Resume" generiert
    • Pause/Resume
      Wenn die Anfrage nach "/pause" oder "/Resume" geht, dann werden die Aktionen ausgeführt und der Status wieder aktualisieren. ein "Pause" ist quasi sofort aktiv. Ein "Resume" aber aktiviert sofort das Gerät aber die Sensoren stehen noch auf Pause, bis Sie das erste mal geprüft wurden.

Das ganze wiederholt sich, bis Sie im PowerShell-Fenster eine Taste drücken unddann die nächste Anfrage kommt. Aus Vereinfachungsgründen wartet der HTTP-Listener endlos und hat keinen Timeout. Das Abbrechen des Skripts mit "CTRL-C" würde den Listener aber nicht beenden. Daher dieser Umweg CTRL-C zu blockieren.

Ein "richtiger Entwickler" würde diese Idee natürlich als "Dienst" schreiben oder als ASPX-Seite auf einem IIS implementieren. Mir geht es ja erst mal um den "Proof of concept" und vielleicht liest Paessler ja mit und integriert so eine Funktion in das Produkt.

Einsatz

Ich kann nun auf jedem überwachten Server einfach http://<prtgserver>:81 aufrufen und erhalte folgenden Bildschirm.

Wer mag, kann gerne den Code um CSS-Formatierungen o.ä. erweitern. Mit reicht es aber um schnell auf dem Server den Status eben dieses Server von PRTG auch ohne Anmeldung zu erhalten und den Server für 15 Minuten auf "Pause" setzen zu können. Mittlerweile gibt es auch einen "ScanNow"-Button und den AckAlarm-Button.

Etwas irritieren kann, dass z.B. Chrome immer ein "?" hinter eine URL hängt und das verschiedene Browser auch eine "/favicon.ico" laden wollen, was entsprechend abgefangen wird.

Beschränkungen

Aufgrund der "Einfachheit" unterliegt das Skript natürlich der ein oder anderen Einschränkung:

  • Kein Multitasking
    Eine Anfragen wird nach der anderen abgearbeitet. Aber der HTTP-Listener "puffert" natürlich schon, d.h. verloren gehen sollte keine Anfrage.
  • Kein Monitoring
    Es ist kein Code enthalten, der dieses Skript selbst überwacht oder Fehler, Probleme, Abbrüche etc. meldet
  • Hosts mit mehreren IPs oder IPv6
    Das Skript sieht natürlich nur die "eine" IP-Adresse der HTTP-Anfrage des Clients. Das muss nicht die Adresse sein, mit der der Host in der Liste gepflegt ist und dann wird er auch nicht gefunden. Nutzen Sie in PRTG als IP-Adresse für das Gerät die, mit der sie von dort per Browser auch reinkommen.
  • Keine Funktion für Server mit lokaler Probe
    Etwas irritiert war ich über doppelte IP-Adressen, bis ich gemerkt habe, dass dies die Server mit einer lokalen "Probe" mit 127.0.0.1 geführt werden. Leider habe ich keinen Weg gefunden, wie man in der Konfiguration für die Probe selbst eine "richtige" IP-Adresse hinterlegen kann. Diese können so also nicht betrachtet werden und werden ignoriert.. Da ich aber meist die Server "remote" überwache, ist dies eine tolerierbare Einschränkung, die ich aber eh nicht ändern kann.
  • Devices mit DNS-Namen
    Meine Kollegen haben die PRTG-Instanz um eine Probe in einem entfernten Netzwerk erweitert, deren Namen mein Skript aber nicht per DNS auflösen kann und die DNS-Auflösung hat die Aufbereitung der Hostliste sehr stark verlangsamt. Daher habe ich die DNS-Auflösung entfernt, mit der Hostnamen zu IP-Adressen aufgelöst werden. In Version 1.3 habe ich daher Hostnamen ausgeschlossen und in 1.4 durch eine ReverseDNS Abfrage ergänzt, d.h. wenn die IP des anfragenden Clients per DNS auf einen Hostnamen aufgelöst wird, der in PRTG als Gerät erfasst wird, wird dieses Gerät ausgegeben.
  • Devices mit gleicher IP-Adresse
    Das PowerShell-Script "sieht" nur die SourceIP und sucht danach in der Konfiguration. Durch mehrere Standorte kann es ebenfalls passieren, dass zwei unterschiedliche Geräte die gleiche IP-Adresse haben. Das PRTGPause-Script kann aber natürlich nur von einer der Adressen erreicht werden, weiß aber nicht welche. Sorgen Sie dafür, dass die IP-Adressen in den Devices eindeutig sind.
  • Abruf hinter NAT oder HTTP-Proxy
    Das Script braucht die Source-IP des Device. Insofern kann es ein Gerät nicht finden, wenn die Client IP durch NAT oder HTTP-Proxies verschleiert wird.

PRTGPause arbeitet also am besten in einem internen gerouteten Netzwerk, bei dem Sie auf dem Server selbst einen Browser starten können, der direkt mit dem PRTGPause-Server kommuniziert und die Geräte mit ihrer IP-Adresse in der Konfiguration hinterlegt sind.

Download

Ich stelle das Skript hier als "Muster" kostenfrei zum Download bereit, kann aber keinen Support dafür liefern. Auch die Firma Paessler wird sicher keinen Support für so ein 3rd-Party-Script leisten können. Der Einsatz erfolgt auf eigene Gefahr. Da der PowerShell-Source aber quasi "offen" ist, können Sie selbst einfach sehen, was es tut und was nicht.

prtgpause.1.4.ps1
prtgpause-template.htm

Kopieren Sie das Skript und die HTM-Datei  einfach auf ihren PRTG-Server, holen Sie sich den PassHash in den Eigenschaften des Benutzers "prtgadmin" und pflegen Sie diesen Hash im Skript ein. Dann noch in der Windows Firewall den Port 81/TCP eingehend öffnen und das Skript als Admin starten. Auf der Console können Sie verfolgen, was das Script beim Zugriff mit einem Browser von einem mit PRTG überwachten Gerät tut.

Einsatz als Hintergrund-Task

Es gibt keine einfache Möglichkeit, ein PowerShell-Script direkt als "Dienst" laufen zu lassen. Dazu müssten ein paar weitere Methoden definiert werden. Aber der Windows Taskplaner kann natürlich das Skript einfach jede Minute starten, wenn es nicht laufen sollte. für den Anfang reicht das sicher. Um den Aufruf im Taskplaner kurz zu halten, habe ich die beiden Dateien mir eine CMD-Datei gebaut:

c:
cd "C:\Program Files (x86)\PRTGPause\"
PowerShell -file "C:\Program Files (x86)\PRTGPause\prtgpause.1.2.ps1"

Die rufe ich im Taskplaner als "SYSTEM" alle Minute auf.

Der Taskplaner selbst startet das Skript natürlich nur einmalig. Das einzige störende ist im Eventlog die Meldung, dass der Task nicht ein zweites mal gestartet wird.

Staging-Area

In der Version 1.2 ist eine Funktion "AckAlarm 15Min" enthalten. Ich habe über die HTTP-API eine Funktionen gesehen, um Alarme zu bestätigen.

/api/acknowledgealarm.htm?id=objectid&ackmsg=yourmessage

Über die GUI kann man aber auch angeben, bis wann Alarme ignoriert werden.

Allerdings funktioniert das in der GUI nur für Sensoren im Alarmzustand aber nicht über Devices. Ich kann noch nicht sehen, ob die funktioniert. Vielleicht tut es ja auch mit dem Parameter "duration=xx", der z.B. bei der Pause-Funktion genutzt werden kann. Das wäre noch zu prüfen.

Zukunft und Bugs

Mein Ziel habe ich erreicht. Ich kann per Browser auf einem PC auf den PRTG-Server gehen, sehen sofort eine zugegeben vereinfachte Ansicht des aktuellen Status ohne eine weitere Anmeldung. Denkbar ist natürlich noch viel mehr, z.B.:

  • Tray-App mit Statusanzeige und Aktionsauswahl
    Dazu sollte ich dem Code aber noch eine Routine einbauen, um den aktuellen Status z.B. als XML-Datei zu liefern. Das ist sicher einfacher weiter zu verarbeiten als ein HTML-Dokument zu parsen.
  • Bildschirmschoner mit PRTG-Status-Anzeige des Servers
    Vielleicht gelingt es mir auch das Hintergrundbild bei gesperrten Server oder angemeldeten Benutzer durch eine Webseite zu ersetzen oder als Bildschirmschoner den Status einzublenden
  • Es gibt anscheinend noch ein Zeichensatzproblem so dass deutsche umlaute nicht korrekt angezeigt werden.

Vielleicht greift jemand meinen Ansatz aus und baut das als "richtiger Programmierer" korrekt. Vielleicht rutscht ja ein solches "Serverportal" in eine zukünftige Version von PRTG. Es ist sicher ein leichtes, die Source-IP einer HTTP-Anfrage auf eine bestimmte URL als gültige Authentifizierung heran zu ziehen, um eine auf den Server optimierte Anzeige bereit zu stellen.

Allerdings muss man dabei beachten, dass es durchaus Systeme gibt, von denen ein "nicht Admin" eine HTTP-Anfrage an den PRTG-Server stellen kann, z.B. ein HTTP-Proxy, ein NAT-Router oder ein Terminal Server. Insofern sollte es pro Gerät vielleicht steuerbar sein, ob zumindest der Zugriff auf die "Pause/Resume"-Funktion eine Kennwortabfrage erfordert.

Windows Lock Screen

Interessant fände ich es natürlich auch, wenn eine App oder einer Dienst auf dem Server den aktuellen Status als Hintergrundbild oder Anmeldebild einblendet. So schwer sollte das ja nicht sein

  • Übersicht über den Sperrbildschirm
    http://msdn.microsoft.com/de-de/library/windows/apps/hh779720.aspx
  • http://praxistipps.chip.de/windows-8-1-sperrbildschirm-personalisieren_12707
  • "Bing My Lockscreen"
  • Chamaeleon
    http://apps.microsoft.com/windows/en-ca/app/chameleon/fa822ed6-c51d-4e3a-a2de-db7adf81eef0
  • GPO
    Computer Configuration\Administrative Templates\System\Logon. Enable the policy “Always use custom login background”
  • Pfade zu den Windows Hintergründen ?
    C:\ProgramData\Microsoft\Windows\SystemData\S-1-5-18\ReadOnly\LockScreen_Z\LockScreen___1680_1050.jpg
    C:\ProgramData\Microsoft\Windows\SystemData\S-1-5-18\ReadOnly\LockScreen_Z\LockScreen___1680_1050_notdimmed.jpg
    (Per Default hat hier aber nur "Trusted Installer" Zugriff, d.h. nicht ma lder Admin
  • 2787100 Win8: How to Manage the Lock Screen Image on Windows 8 and Windows Server 2012
    The new group policy is named “Force a specific default lock screen image” and can be found in this path in the group policy editor: “Computer Configuration\Policies\Administrative Templates\Control Panel\Personalization”
    (nur Win 8 Enterprise und Win8 Server)
  • Sign in Screen - Change Background Color in Windows 8:
    http://www.eightforums.com/tutorials/15554-sign-screen-change-background-color-windows-8-a.html
  • Hintergrundfarbe HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\Accent\DefaultColorSet:DWORD32 = give it a value with the base of 2.
  • Windows 8 Pro Safeguarding, Bonus 1: Replace the Default Lock Screen
    http://www.youtube.com/watch?v=Yusczt18RGg
  • http://winaero.com/comment.php?comment.news.190

Weitere Links