marcimarc85
Goto Top

PRTG Monitoring mittels Powershell pausieren

Hallo,

Ich habe online ein bereit fertiges Script gefunden, mit dem ich unser PRTG Monitoring pausieren möchte:

Das Script habe ich etwas angepasst / gekürzt, um es meinen Bedürfnissen anzupassen:

param(            
[parameter(Mandatory=$true)][string]$todo  # jeweilige Funktion ansteuern                      
) 


#######################################################
# Load environment
#######################################################

. "$PSScriptRoot\enterprise_environment.ps1"  


#######################################################
# pause monitoring
#######################################################

            
$benutzer = "mein_username" # Credentials hinterlegen              
$passhash = "mein_passhash"              
            
$prtg_url = "https://meine_URL" # URI von PRTG Core Server              
            
function invoke-PRTGsenpausieren { # Funktion erstellen zum pausieren            
param(            
[parameter(Mandatory=$true)][int]$prtg_objectid,            
[parameter(Mandatory=$false)][int]$dauer,            
[parameter(Mandatory=$false)][string]$nachricht            
            
)            
            
[string]$sensorpausierenuri = "$prtg_url/api/pauseobjectfor.htm?id=$prtg_objectid&pausemsg=$nachricht&duration=$dauer&username=$benutzer&passhash=$passhash" # URI zum pausieren              
Invoke-RestMethod -uri $sensorpausierenuri # Rest-Schnittstellen-Aufruf            
            
}            
            
function invoke-PRTGsenfortfahren { # Funktion erstellen zum fortfahren            
param(            
[parameter(Mandatory=$true)][int]$prtg_objectid            
            
)            
            
[string]$sensorfortfahrenuri = "$prtg_url/api/pause.htm?id=$prtg_objectid&action=1&username=$benutzer&passhash=$passhash" # URI zum fortfahren              
Invoke-RestMethod -uri $sensorfortfahrenuri            
            
}            
                     
            
            
switch( # Switch-Funktion            
$todo # Parameter von Zeile 2            
){            
fortfahren { # Wenn String fortfahren lautet            
    invoke-PRTGsenfortfahren -objektid $prtg_objectid # Sensor fortfahren            
    }catch{            
    write-host "fortfahren war nicht möglich wegen Fehler $($error[-1])" -ForegroundColor Yellow # Abfangen von Exceptions              
    }            
    
              
            
           
            
pausieren { # Wenn String pausieren lautet            
   
    write-host $prtg_objectid                 
    invoke-PRTGsenpausieren -objektid $prtg_objectid -dauer $dauer -nachricht $nachricht # Sensor pausieren            
    }catch{
    write-host "pausieren war nicht möglich wegen Fehler $($error[-1])" -ForegroundColor Yellow # Abfangen von Exceptions              
    }            
    
             
            
            
} #ende von switch           

im Pausieren-Switch habe ich mir einmal per Write-Host die Variable prtg_objectid ausgeben lassen. Sie wird dort beim Ausführen des Scripts auch korrekt ausgegeben. Die prtg_obectid Variable ist in der enterprise_environment.ps1 definiert, die zu Beginn geladen wird.

Wenn ich das Script nun aber ausführe mit einem der beiden switche, bekomme ich folgende Fehlermeldung:

PS D:\> D:\powershell_tools\start_stop_prtg.ps1
Cmdlet start_stop_prtg.ps1 an der Befehlspipelineposition 1
Geben Sie Werte für die folgenden Parameter an:
todo: pausieren
6222
invoke-PRTGsenpausieren : Es wurde kein Parameter gefunden, der dem Parameternamen "objektid" entspricht.  
In D:\railsys\enterprise\bin\powershell_tools\start_stop_prtg.ps1:74 Zeichen:29
+     invoke-PRTGsenpausieren -objektid $prtg_objectid -dauer $dauer -nachricht $n ...
+                             ~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [invoke-PRTGsenpausieren], ParameterBindingException
    + FullyQualifiedErrorId : NamedParameterNotFound,invoke-PRTGsenpausieren

Ich verstehe nicht, warum mir der korrekte Variablenwert ausgegeben wird, dann aber im Invoke-Befehl nicht mehr erkannt wird. Mit $Using:variable kann ich an der Stelle auch niht arbeiten

Content-ID: 42417428332

Url: https://administrator.de/contentid/42417428332

Ausgedruckt am: 21.11.2024 um 17:11 Uhr

13034433319
13034433319 17.06.2024 aktualisiert um 12:53:07 Uhr
Goto Top
Es wurde kein Parameter gefunden, der dem Parameternamen "objektid" entspricht
Der Parametername der Funktion heißt ja auch -prtg_objectid und nicht -objektid. Fehlermeldung lesen hilft
[parameter(Mandatory=$true)][int]$prtg_objectid,
Genau so hier ist der Fehler auch vorhanden
invoke-PRTGsenfortfahren -objektid $prtg_objectid # Sensor fortfahren

Und Code vernünftig einrücken hilft ungemein beim lesen und Fehler entdecken ...

Gruß
MarciMarc85
MarciMarc85 17.06.2024 um 12:38:05 Uhr
Goto Top
Sorry, hatte veregssen die Quelle des Scripts zu verlinken. Da heißt der Parametername auch anders, als die Variabel:

https://germanpowershell.com/prtg-api-pausieren-fortfahren-bestaetigen/

Aber das scheint tatsächlich der Grund gewesen zu sein. Zumindest bekomme ich jetzt die Meldung

Invoke-RestMethod : Die Anfrage wurde abgebrochen: Es konnte kein geschützter SSL/TLS-Kanal erstellt werden..
13034433319
13034433319 17.06.2024 aktualisiert um 12:45:21 Uhr
Goto Top
Veraltetes Windows verwendet? Windows 7? Oder nicht von Windows nicht vertrauenswürdiges Zertfikat auf dem PRTG verwendet? Dann CA ins Machine Root importieren, oder Cert vertrauen und Protokoll festlegen

[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
[System.Net.ServicePointManager]::SecurityProtocol = 'Tls12'  

Wenn Windows 7 verwendet wird kannst du es eh knicken da fehlen mittlerweile neue TLS Ciphers.
MarciMarc85
MarciMarc85 17.06.2024 um 13:00:39 Uhr
Goto Top
Ja. der PRTG Server läuft über https mittels eines selbstsignierten Zertifikats.

Ich habe nun folgendes an den Anfang des Scripts geschrieben:

$AllProtocols = [System.Net.SecurityProtocolType]'Tls11,Tls12'  
[System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}

Damit ist die Fehlermeldung auch verschwunden. Taucht nun aber folgendes auf:

Invoke-RestMethod : Die zugrunde liegende Verbindung wurde geschlossen: Unerwarteter Fehler beim Senden..
In D:\powershell_tools\start_stop_prtg.ps1:32 Zeichen:1
+ Invoke-RestMethod -uri $sensorpausierenuri # Rest-Schnittstellen-Aufruf
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
13034433319
13034433319 17.06.2024 aktualisiert um 13:09:13 Uhr
Goto Top
Installiere das Cert im Root Machine store... Ansonsten fehlen bei dir TLS Ciphers oder die URL hat Fehler. Welches OS? Welche PS Version?

p.s. einem Skript von 2019 würde ich nicht mehr vertrauen da kann sich zwischenzeitlich schon so einiges geändert haben, zumal das echt schrottig autgebaut ist.
ThePinky777
ThePinky777 17.06.2024 um 13:37:54 Uhr
Goto Top
nur ne frage am rande, für was willst du das einsetzen?
also warum?

Weil du kannst ja im PRTG einzelne Geräte oder PRTG ebenfalls mit nem Mausklick pausieren.
oder du kannst nen Zeitplan einstellen das zu gewissen uhrzeiten pausiert werden soll usw...
daher erschliesst sich mir der sinn und nutzen des steuerns per powershell nicht so ganz.
MarciMarc85
MarciMarc85 17.06.2024 um 15:17:01 Uhr
Goto Top
Ganz einfach:
- ca 100 Server, die überwacht werden
- über 2300 Sensoren in Summe
- täglichen werden unterschiedliche Server per Script austomatisch geupdated
- Wenn diese Server geupdated werden, möchte ich, dass das Script die entsprechende Object-ID vom jeweilgen Server pausiert und wieder startet, sobald as Update durch ist.

Das verhindet einen haufen unnötiger Mails, weil Sensoren während des Updates in den Fehlerzustand wechseln

In der vergangenhait hatte ich das bei einigen Systemen per batch-Script realisiert. dort wird der entsprechende Befehl an die PRTG API per curl-Befehl gesendet. Das hatte ich mal so vom Paessler Support empfohlen bekommen. Nachteil ist aber auch, dass man auf allen Servern zusätzlcih Curl installieren muss.

Möchte auch gern alles per Powershell machen. Aber jetzt scheitert das scheinbar an der Zertifikatsgeschichte. Habe jetzt schon ein selbstsigniuertes Zertifikat erstellt, alle Möglichen Parameter im Script hinzugefügt, die die SSL Abfrage ignorieren sollten, bzw. nur TLS 1.2 akzeptiert.

$AllProtocols = [System.Net.SecurityProtocolType]'Tls11,Tls12'  
[System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}

oder :

add-type @"   
   using System.Net;
    using System.Security.Cryptography.X509Certificates;
    public class TrustAllCertsPolicy : ICertificatePolicy {
        public bool CheckValidationResult(
            ServicePoint srvPoint, X509Certificate certificate,
            WebRequest request, int certificateProblem) {
            return true;
        }
    }
"@  
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

Aber trotzdem bleibt der Fehler :

Invoke-WebRequest : Die zugrunde liegende Verbindung wurde geschlossen: Unerwarteter Fehler beim Senden..
ThePinky777
ThePinky777 17.06.2024 aktualisiert um 15:59:24 Uhr
Goto Top
selbsterstelltest zertifikat >> haben die server entsprechendes Zertifikat der CA als vertrauensvoll drin?
also von deinem CA Server mit dem das Zertifikat erstellt wurde.
Oder hast du nur ein lokales Zerfitikat gemacht, dem vertrauen die Server logischer weise nicht, musst ihnen das auch erst einspielen damit sie dem vertrauen.
ThePinky777
ThePinky777 17.06.2024 aktualisiert um 16:08:49 Uhr
Goto Top
oder umgehe das indem du remote das script direkt auf dem PRTG Server startest:

Bedeutet auf dem Server (hier Beispiel: SERVER001) der PRTG sagen soll schalte Sensor ab:

Invoke-Command -ComputerName PRTG-SERVER-NAME -ScriptBlock {
POWERSCRIPT BEFEHLE ZEILEN HIER EINFüGEN
z.B. Powershell Script ausführen das liegt under c:\scripts\SERVERNAME001.ps1

"C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe"  -executionpolicy Unrestricted -File "c:\scripts\SERVERNAME001.ps1"  

} 

Und in die SERVERNAME001.ps1 codeste hart rein welche sensoren deaktiviert werden sollen.

Dann hast kein problem mit Webrequest TLS und SSL usw... und wenn dann führt jda der PRTG server das lokal aus und vertraut sich selbst hoffentlich face-smile

"Nachteil" hier das script muss auf dem SERVER001 ausgeführt werden mit ner Kennung die lokaler admin auf PRTG ist. Wenns im Sceduled Task ist eben mit einer Kennung die entsprechende Rechte hat.
13034433319
13034433319 17.06.2024 aktualisiert um 16:54:19 Uhr
Goto Top
Wenn du liebenswürdigerweise erst mal meine Fragen beantworten würdest, die ignorierst du alle schon seit Anfang des Threads sind aber essentiell, so macht das keinen Spaß wenn man immer gegen eine Wand redet und nichts zurück kommt face-confused ... Die Meldung liegt zu 99,9 Prozent an non matching TLS-Ciphers von Schannel mit dem PRTG Server (damit meine ich nicht die TLS Version!) oder non matching Common-Name zur URL. Sieht man übrigens auch schön in Wireshark ...
https://www.nartac.com/Products/IISCrypto

Supportete Cryptos vom Zielserver lassen sich bspw. mit nmap auflisten
nmap --script ssl-enum-ciphers -p 443 X.X.X.X

Da kommt dann bspw. so was raus

screenshot
MarciMarc85
MarciMarc85 18.06.2024 um 12:41:22 Uhr
Goto Top
Zitat von @13034433319:

Veraltetes Windows verwendet? Windows 7? Oder nicht von Windows nicht vertrauenswürdiges Zertfikat auf dem PRTG verwendet? Dann CA ins Machine Root importieren, oder Cert vertrauen und Protokoll festlegen

[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
[System.Net.ServicePointManager]::SecurityProtocol = 'Tls12'  

Wenn Windows 7 verwendet wird kannst du es eh knicken da fehlen mittlerweile neue TLS Ciphers.


Die Server auf denen das Script läuft haben alle unterschiedliche Windows Versionen (Win Server 2012 -2022)
13034433319
13034433319 18.06.2024 aktualisiert um 14:08:21 Uhr
Goto Top
Win Server 2012
eqiv. zu W7 kannst du damit knicken.

Cipher wie oben geschrieben abgleichen dann siehst du was geht und was nicht. Simple and effektive ...
MarciMarc85
MarciMarc85 19.06.2024 um 06:43:24 Uhr
Goto Top
@13034433319 du hat Recht. Auf nem Server >= Server 2012 läuft das Script ohne Fehler.
Dann muss ich das jetzt irgendwie noch lauffähig für 2012 bekommen.
13034433319
13034433319 19.06.2024 aktualisiert um 07:37:06 Uhr
Goto Top
Zitat von @MarciMarc85:
Dann muss ich das jetzt irgendwie noch lauffähig für 2012 bekommen.
Mit schannel bekommst du das da aus Prinzip nicht hin da musst du auf externe SSL Bibliotheken auaweichen wie bspw. mit curl .
Den Server jetzt aussondern wäre die klügere Wahl ... Oder die Aufgabe einfach andere Stationen erledigen lassen, per Trigger von dem Altertümchen ist das ja kein Problem.
MarciMarc85
MarciMarc85 19.06.2024 um 07:56:46 Uhr
Goto Top
Dann muss ich das wohl über curl weiterhin erledigen lassen. Das hat im Batch_Script bisher immer gut funktioniert. Ist halt nur leider immer dieser Extra Scritt curl zu installieren. Ich versuche generell zu vermeiden Zusatzsoftware installieren zu müssen.
13034433319
13034433319 19.06.2024 aktualisiert um 08:05:15 Uhr
Goto Top
Curl gibts doch portable , da muss man nix installieren.

Aber wie gesagt mit einem Tasktrigger auf einem Remotesystem das man vom alten System aus per simplem Eventlog Eintrag aus triggert klappt es auch ohne extra Tools.