Zur Überwachung des Lastenausgleichs einer Citrix XenApp-Server-Umgebung war es notwendig die Befehlsausgabe von qfarm /load via XML im PRTG einzulesen. Es besteht hierbei natürlich die Möglichkeit dies für andere Systeme und Befehle zu verwenden.

Eine typische Ausgabe von qfarm /load ist:

prtg_gfarm_load_example

Bei meinen Tests habe ich zwei Varianten erfolgreich testen können. Ich persönlich bevorzuge Variante 1 mit PowerShell. Variante 2 via batch-Skripte und Freigabe hat den Nachtteil, das ggf. das Skript per Hand gestartet und zusätzlich die Ausführung überwacht werden muss. Kann aber im Bedarfsfall ein guter Ersatz sein.

Variante 1 – via Powershell-Skript:

Bei dieser Variante mittels Powershell muss zunächst sichergestellt werden, dass der Remote-Server sogenannte Invoke-Commands erfolgreich akzeptiert. Dies machen wir auf unserem PRTG-Server mittels dem Powershell-Befehl:

  • test-wsman <Remote-Server>

Wenn die Konfiguration noch nicht korrekt ist, erhalten wir folgende Meldung:

prtg_powershell_test

In diesem Fall führen wir die folgenden Befehle aus:

  • Enable-PSRemoting -Force
  • Set-Item wsman:\localhost\client\trustedhosts *
  • Restart-Service WinRM

Wer nicht allen Systemen die Remote-Ausführung von PowerShell-Befehlen gestatten will muss das * im zweiten Befehl mit einer Liste der gewünschten Systeme austauschen.

  • Set-Item wsman:\localhost\client\trustedhosts „server01, server02“

Hinweis: Bei jeder Änderung muss der dritte Befehl erneut ausgeführt werden.

Wenn die Konfiguration korrekt ist erhalten wir zur Ausführung des PowerShell-Befehls:

  • test-wsman <Remote-Server>

prtg_powershell_test_success

Hinweis: Zum erweiterten Test, mit der Möglichkeit PowerShell-Befehle direkt auf dem Remote-Server ausführen zu können und dass die bestehenden Rechte ausreichend sind, stehen folgende PowerShell-Befehle zur Verfügung:

  • Enter-PSSession -ComputerName
  • Enter-PSSession -ComputerName <Remote-Server> -Credential <Remote-Username>

Jetzt erstellen wir auf unserem Remote-Server ein geeignetes Verzeichnis und hinterlegen dort eine entsprechende Skript-Datei. In meinem Fall C:\PRTG und:

  • prtg_get_qfarm_load.ps1

In dieser Datei hinterlegen wir folgenden Code:

Set-ExecutionPolicy Unrestricted

[string]$cmd = 'qfarm'
[string]$par = '/load'

[array]$cmdoutput = & $cmd $par

$cmdoutput = $cmdoutput[3..($cmdoutput.length)]

Write-Host '<?xml version="1.0" encoding="Windows-1252" ?>'
Write-Host '<prtg>'

foreach ($line in $cmdoutput) {

 $line = $line -replace '\s+', ' '

 $lineparts = $line.Split(' ')

 Write-Host ' <result>'
 Write-Host -Separator '' '  <channel>'$lineparts[0]' - LOAD</channel>'
 Write-Host -Separator '' '  <value>'$lineparts[1]'</value>'
 Write-Host '  <unit>Load</unit>'
 Write-Host '  <float>0</float>'
 Write-Host '  <LimitMaxError>10000</LimitMaxError>'
 Write-Host '  <LimitErrorMsg>Server'$lineparts[0]'ist maximal ausgelastet. Prozessorlast bzw. RAM-Nutzung zu hoch. Bitte korrigieren!</LimitErrorMsg>'
 Write-Host '  <showChart>1</showChart>'
 Write-Host '  <showTable>1</showTable>'
 Write-Host '  <LimitMode>1</LimitMode>'

 Write-Host ' </result>'

}

Write-Host '</prtg>'

Führen wir nun die Datei in der powershell aus bekommen wir eine Ausgabe ähnlich:

prtg_qfarm_load_ps1_test

Jetzt müssen wir nur noch auf unserem PRTG-Server dafür sorgen, dass dieses Skript remote aufgerufen wird. Hierzu erstellen wir auf unserem PRTG-Server im Verzeichnis:

C:\Program Files (x86)\PRTG Network Monitor\Custom Sensors\EXEXML

eine entsprechende PowerShell-Datei. In meinem Fall:

  • prtg_get_qfarm_load_remote.ps1

In dieser Datei fügen wir folgenden kurzen Code ein:

Invoke-Command -ComputerName $args[0] -ScriptBlock { & C:\PRTG\prtg_get_qfarm_load.ps1 }

Hinweis: Ggf. den Namen der PowerShell-Datei auf dem Remote-Server anpassen!

Zum Test wechseln wir in die Powershell und rufen das Skript mit dem Computernamen des Remoteservers als alleiniges Argument auf:

& 'C:\Program Files (x86)\PRTG Network Monitor\Custom Sensors\EXEXML\prtg_get_qfarm_load_remote.ps1' <Remote-Server>

und erhalten als Beispiel:

prtg_qfarm_load_remote_ps1_test

Hinweis: Zur Ausführung des Befehls auf meinem PRTG-Server steht oben rechts PS. Wenn durch Tests mit Eurem Remote-Server dort dessen Name zu sehen ist, arbeitet ihr in der PowerShell auf dem falschen System!

Im PRTG selbst fügen wir bei unserem bestehenden Server einen neuen Sensor vom Typ:

  • Programm/Skript (erweitert)

hinzu. Im zweiten Schritt ist zwingend darauf zu achten, dass der Sicherheitskontext auf „Die Anmeldedaten für Windows des übergeordneten Geräts verwenden“ gesetzt ist und unser Skript ausgewählt ist. Bitte beachten dass ggf. die Anmeldeinformationen vom Server gesetzt werden müssen.

prtg_qfarm_load_add_sensor.jpg

Nach zweimaliger Ausführung des Skripts durch den Server sehen wir nun:

prtg_qfarm_load_final_sensor_v2

 

Variante 2 – via batch-Skripte und Freigabe

Eine zweite Variante, die ich mir im Vorfeld überlegt und getestet habe, ist die lokale Ausführung eines batch-Skriptes, in einer Schleife, auf dem Remote-Server.

Hierzu habe ich auf dem Remote-Server ein Verzeichnis PRTG angelegt und als PRTG$-Freigabe für den PRTG-Server verfügbar gemacht.

In das Verzeichnis habe ich eine Datei: prtg_get_qfarm_load.bat erstellt.

@echo off

SET "TEMPOUTPUTFILE=C:\PRTG\prtg_get_qfarm_load.tmp"
SET "OUTPUTFILE=C:\PRTG\prtg_get_qfarm_load.xml"

:LOOP

if NOT "%OUTPUTFILE%" == "" (

 (

 echo ^<?xml version="1.0" encoding="Windows-1252" ?^>
 echo ^<prtg^>

 for /f "skip=2 tokens=1,2 delims= " %%a in ('qfarm /load ^| findstr /v /r /i "^--"') do (

  echo ^<result^>
  echo  ^<channel^>%%a - LOAD^</channel^>
  echo  ^<value^>%%b^</value^>
  echo  ^<unit^>Load^</unit^>
  echo  ^<float^>0^</float^>
  echo  ^<LimitMaxError^>10000^</LimitMaxError^>
  echo  ^<LimitErrorMsg^>Server %%a ist maximal ausgelastet. Prozessorlast bzw. RAM-Nutzung zu hoch. Bitte korrigieren! ^</LimitErrorMsg^>
  echo  ^<showChart^>1^</showChart^>
  echo  ^<showTable^>1^</showTable^>
  echo  ^<LimitMode^>1^</LimitMode^>
  echo ^</result^>

  )

 echo ^</prtg^>
 ) > "%TEMPOUTPUTFILE%"

move %TEMPOUTPUTFILE% %OUTPUTFILE%

TIMEOUT /T 10 /NOBREAK > nul
GOTO LOOP

)

 

Zur Ausführung der Skript-Datei wird eine Temp-Datei als XML erzeugt, da die Ausführungszeit von qfarm /load ggf. zu lang ist und das Ergebnis vom PRTG-Server nicht vollständig gelesen wird. In diesem Fall hätten wir einen Fehler im PRTG. Nach Abschluss der Generierung der Temp-Datei wird diese in die Zieldatei umbenannt und die alte XML-Datei überschrieben. Das Skript führt die Schleife alle 10 Sekunden aus.

Damit diese Batch-Datei auf dem Server nicht sichtbar ist, habe ich diese mit dem Tool Bat-To-Exe-Converter, Portable Variante, mit folgendem Befehl in eine exe-Datei umgewandelt:

Bat_To_Exe_Converter.exe -bat c:\prtg\prtg_get_qfarm_load.bat -save c:\prtg\prtg_get_qfarm_load.exe -invisible

Durch einmalige manuelle Ausführung der prtg_get_qfarm_load.exe-Datei wird nun alle 10 Sekunden die gewünschte XML-Datei generiert.

Hinweis: Um diesen Vorgang beenden zu können, muss der laufende Prozess prtg_get_qfarm_load.exe über den TaskManager oder taskkill-Befehl beendet werden (Bsp.: taskkill /F /IM prtg_get_qfarm_load.exe /T).

Hinweis: Meine ursprüngliche Idee war die Erstellung eines Dienstes mit dem Befehl sc create. Leider war dies nicht erfolgreich. Wer hierzu erfolgreich eine exe-Datei als Dienst aktivieren konnte, mir bitte einen Kommentar senden. Gerne hinterlege ich hier die funktionierende Variante.

Zum Abruf der Daten in der XML-Datei ist erforderlich dies über ein Skript ans PRTG zu übergeben. Nach Auskunft vom PRTG-Support besteht nicht die Möglichkeit XML-Dateien direkt einzulesen.

Auf dem PRTG-Server, im Verzeichnis C:\Program Files (x86)\PRTG Network Monitor\Custom Sensors\EXEXML habe ich eine Datei read_prtg_get_qfarm_load.bat erstellt, deren Aufgabe lediglich die Ausgabe des Dateiinhaltes ist.

@echo off
type \\<remote-server>\prtg$\prtg_get_qfarm_load.xml

Im PRTG selbst fügen wir bei unserem bestehenden Server einen neuen Sensor vom Typ:

  • Programm/Skript (erweitert)

hinzu und wählen dass von uns hinterlegte Skript aus:

prtg_qfarm_load_batch_add_sensor

Auch hier sehen wir nach zweimaliger Abfrage des Sensors:

prtg_qfarm_load_batch_final_sensor

 

Quellen:

Advertisements