charismea
Goto Top

Ping Abfrage mit IF ELSE in PowerShell

Hallo zusammen

Ich habe ein kleines Problemchen, welches ich nicht weiss wie zu lösen.
Ich möchte mit einer Ping Abfrage in PowerShell sicherstellen, dass das Zielsystem erreichbar ist und erst dann das Script weiterlaufen lassen.

Ich habe es bisher mit einer Schleifenfunktion gelöst:

  1. Schleifenfunktion bis Gegenstelle erreicht
while (!(Test-Connection xx.xx.xx.xx -Count 1 -quiet)){
sleep(1)
}

Ich möchte diese aber eher durch eine IF/ELSE-Anweisung und zum Beispiel nur für 10 Ping Abfragen lösen.

Könnt Ihr mir hier helfen?
Ich danke für Inputs.

Content-Key: 1917604874

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

Printed on: April 16, 2024 at 14:04 o'clock

Member: NordicMike
NordicMike Feb 15, 2022 at 07:14:52 (UTC)
Goto Top
Was willst du erreichen? Eine gewisse Logik zum Auswerten oder einfach nur eine 10 Sekunden Pause?
Member: Doskias
Doskias Feb 15, 2022 at 07:33:43 (UTC)
Goto Top
Moin,

wenn du es aber mit IF-Else machst, dann wird es nur einmalig geprüft. Wenn du aber warten willst, bis der Rechner da ist, ist While schon richtig.

Ansonsten in Worten:
IF (Ping erfolgreich)
{ führe Skript aus}
else
{führe irgendwas anderes aus}

Gruß
Doskias
Member: manuel-r
manuel-r Feb 15, 2022 at 08:01:03 (UTC)
Goto Top
Ich möchte diese aber eher durch eine IF/ELSE-Anweisung und zum Beispiel nur für 10 Ping Abfragen lösen.

Dann machst du es trotzdem mit WHILE zählst aber in der Schleife einen Zähler hoch und verlässt die Schleife mit BREAK sobald der Zähler den Wert X erreicht hat.

Manuel
Member: Charismea
Charismea Feb 15, 2022 at 08:31:36 (UTC)
Goto Top
und wie müsste dies konkret als Code aussehen?
-> resp. wie speichert es den erfolgreichen Ping als Wert?
Member: Doskias
Doskias Feb 15, 2022 at 08:32:02 (UTC)
Goto Top
Zitat von @manuel-r:

Ich möchte diese aber eher durch eine IF/ELSE-Anweisung und zum Beispiel nur für 10 Ping Abfragen lösen.

Dann machst du es trotzdem mit WHILE zählst aber in der Schleife einen Zähler hoch und verlässt die Schleife mit BREAK sobald der Zähler den Wert X erreicht hat.

Manuel

Jetzt hab ich erst verstanden was mit 10 Ping abfragen gemeint ist.

Das macht aber keinen Sinn. Wenn ich jetzt:
while (!(Test-Connection xx.xx.xx.xx -Count 1 -quiet)){
sleep(1)
}
mit nem counter 10 mal hoch zähle, dann habe ich im Endeffekt das gleiche Ergebnis wie bei
Test-Connection xx.xx.xx.xx -Count 10 -quiet
. Oder habe ich da jetzt einen Denkfehler?

Ob ich jetzt einen Ping schicke, eine Sekunde warte und die Schleife 10 mal wiederhole oder ob ich einmal 10 Pings im Sekundenabstand schicke ist im Effekt dann auch egal, oder?

Gruß
Doskias
Member: Charismea
Charismea Feb 15, 2022 at 08:37:01 (UTC)
Goto Top
Ich möchte erreichen, dass wenn die Ziel-IP 10x erreicht wird, das nachfolgende Script ausgeführt wird und bei nicht erreichen, das Script gar nichts tut.
Member: Doskias
Doskias Feb 15, 2022 at 08:43:06 (UTC)
Goto Top
Zitat von @Charismea:

und wie müsste dies konkret als Code aussehen?
-> resp. wie speichert es den erfolgreichen Ping als Wert?

Brauchst du ja nicht speichern.

Du machst deine while-Schleife wie bisher, packst n braeak und counter rein und baust es in eine if. also etwa so:

$counter=0
while (!(Test-Connection xx.xx.xx.xx -Count 1 -quiet)
{
if (!(test-connection xxx.xxx.xxx.xxx -count 1 -quiet))
{dein code + break"}  
else
{$counter ++
if ($counter -ge 10)
{break}

"}  
}
Member: StefanKittel
StefanKittel Feb 15, 2022 updated at 08:43:39 (UTC)
Goto Top
Moin,

ping zeigt über den Errorlevel an ob das Ziel erreichbar war.
Das kannst Du in Deiner Schleife verwenden.

Ein Einzelping ("Geben Sie mir ein Ping Vasili, aber bitte nur ein einziges")
ping 8.8.8.8 -n 1
Ping wird ausgeführt für 8.8.8.8 mit 32 Bytes Daten:
Antwort von 8.8.8.8: Bytes=32 Zeit=12ms TTL=59

Ping-Statistik für 8.8.8.8:
    Pakete: Gesendet = 1, Empfangen = 1, Verloren = 0
    (0% Verlust),
Ca. Zeitangaben in Millisek.:
    Minimum = 12ms, Maximum = 12ms, Mittelwert = 12ms

echo %errorlevel%
0

ping 8.8.8.1 -n 1
Ping wird ausgeführt für 8.8.8.1 mit 32 Bytes Daten:
Zeitüberschreitung der Anforderung.

Ping-Statistik für 8.8.8.1:
    Pakete: Gesendet = 1, Empfangen = 0, Verloren = 1
    (100% Verlust),

echo %errorlevel%
1
Member: manuel-r
manuel-r Feb 15, 2022 at 08:56:44 (UTC)
Goto Top
Ich möchte erreichen, dass wenn die Ziel-IP 10x erreicht wird, das nachfolgende Script ausgeführt wird und bei nicht erreichen, das Script gar nichts tut.

Und warum negierst du dann Test-Connection? Viel mehr Sinn macht dann
while (Test-Connection xx.xx.xx.xx -Count 1 -quiet) {
 $Counter = $Counter + 1
 sleep(1)
 if ($Counter -eq 10) {
  break
 }
}
write-host "Hier geht es weiter"  
oder
Do {
 if (Test-Connection xx.xx.xx.xx -Count 1 -Quiet) {
 $Counter = $Counter + 1
 start-sleep -s 1
 }
} Until ($Counter -eq 10)
write-host "Hier geht es weiter"  
Mitglied: 1915348599
1915348599 Feb 15, 2022 at 11:26:50 (UTC)
Goto Top
$cnt = 0
while($cnt -lt 10){
    if (Test-Connection xx.xx.xx.xx -Count 1 -Quiet){$cnt++}Else{$cnt=0}
    sleep 1
}
Member: Doskias
Doskias Feb 15, 2022 at 13:08:38 (UTC)
Goto Top
Moin
Zitat von @1915348599:
$cnt = 0
while($cnt -lt 10){
    if (Test-Connection xx.xx.xx.xx -Count 1 -Quiet){$cnt++}Else{$cnt=0}
    sleep 1
}
Das macht doch keinen Sinn. Du setzt CNT auf 0, ok damit startest du die while schleife. Wenn die Test-Connection positiv ist, also der Rechner erreichbar ist, dann wird es um 1 hochgezählt. Läuft also bei aktiven Rechner 10 mal durch. Wenn der Rechner aus ist, wird CNT wieder auf 0 gesetzt. Ist der Rechner also aus werden nicht nur 10, sondern unendlich viele Ping-Abfragen gesendet. Wie hilft das weiter?

Gruß
Doskias
Mitglied: 1915348599
1915348599 Feb 15, 2022 updated at 13:23:16 (UTC)
Goto Top
Zitat von @Doskias:
Das macht doch keinen Sinn. Du setzt CNT auf 0, ok damit startest du die while schleife. Wenn die Test-Connection positiv ist, also der Rechner erreichbar ist, dann wird es um 1 hochgezählt. Läuft also bei aktiven Rechner 10 mal durch. Wenn der Rechner aus ist, wird CNT wieder auf 0 gesetzt. Ist der Rechner also aus werden nicht nur 10, sondern unendlich viele Ping-Abfragen gesendet. Wie hilft das weiter?
Doch das macht schon Sinn (für den TO), es wird bei dieser Variante nur weitergemacht wenn 10 aufeinander folgende Pings erfolgreich sind. Ist dazwischen einer nicht erfolgreich fängt die Zählung wieder bei 0 an, so lange bis 10 aufeinanderfolgende Pings erfolgreich sind. Der TO wollte das ja so oder so ähnlich, ist eben nicht so ganz klar formuliert:

Ich möchte erreichen, dass wenn die Ziel-IP 10x erreicht wird, das nachfolgende Script ausgeführt wird und bei nicht erreichen, das Script gar nichts tut.
Member: Doskias
Doskias Feb 15, 2022 at 13:27:12 (UTC)
Goto Top
Zitat von @1915348599:

Zitat von @Doskias:
Das macht doch keinen Sinn. Du setzt CNT auf 0, ok damit startest du die while schleife. Wenn die Test-Connection positiv ist, also der Rechner erreichbar ist, dann wird es um 1 hochgezählt. Läuft also bei aktiven Rechner 10 mal durch. Wenn der Rechner aus ist, wird CNT wieder auf 0 gesetzt. Ist der Rechner also aus werden nicht nur 10, sondern unendlich viele Ping-Abfragen gesendet. Wie hilft das weiter?
Doch das macht schon Sinn (für den TO), es wird bei dieser Variante nur weitergemacht wenn 10 aufeinander folgende Pings erfolgreich sind. Ist dazwischen einer nicht erfolgreich fängt die Zählung wieder bei 0 an, so lange bis 10 aufeinanderfolgende Pings erfolgreich sind. Der TO wollte das ja so auch wenn das nicht so ganz klar formuliert ist:

Ich möchte erreichen, dass wenn die Ziel-IP 10x erreicht wird, das nachfolgende Script ausgeführt wird und bei nicht erreichen, das Script gar nichts tut.

Ok, dennoch hast du am Ende die Situation, dass du extrem leicht in eine Endlosschleife verfallen kannst. Die ganze Anfrage des TO ist für mich immer noch nicht bis zum Ende durchdacht. Will ich 10 Pings dann mach ich n -count 10. 10 Pings in Folge mit einem Abstand von einer Sekunde einzeln abzufragen ist sinnfrei. Entweder der Rechner ist da oder nicht. In einer Sekunde wird sich da nicht viel tun.
Mitglied: 1915348599
1915348599 Feb 15, 2022 updated at 13:34:24 (UTC)
Goto Top
Zitat von @Doskias:
Ok, dennoch hast du am Ende die Situation, dass du extrem leicht in eine Endlosschleife verfallen kannst.
Nur so lange der Rechner eben nicht online ist.
Die ganze Anfrage des TO ist für mich immer noch nicht bis zum Ende durchdacht.
Dito, ist für mich auch ehrlich gesagt sinnfrei.
Will ich 10 Pings dann mach ich n -count 10. 10 Pings in Folge mit einem Abstand von einer Sekunde einzeln abzufragen ist sinnfrei. Entweder der Rechner ist da oder nicht. In einer Sekunde wird sich da nicht viel tun.
Ich schätze mal er versucht damit ein Delay zu erreichen bis ein Rechner komplett hochgefahren ist (der Netzerkstack antwortet ja oftmals schon früher als später gestartete Dienste), und kennt mangels Wissen keine andere Möglichkeit wie man erkennt das ein Dienst erreichbar ist ... aber für so was gibt es ja weit bessere Methoden als Pings um das festzustellen ...

Glaskugel polier ... ende.
Member: Charismea
Charismea Feb 15, 2022 at 22:18:06 (UTC)
Goto Top
Hallo

Ich versuche mich nochmals klar auszudrücken. Es geht um ein Script, welcher einen Parameter nur ändern sollte, wenn eine bestimmte Ziel-IP erreicht wird. Dies, damit sichergestellt werden kann, dass sich der entsprechende Host im richtigen Netzwerk befindet.

Mein bisheriges komplettes Script:
# Schleifenfunktion bis Gegenstelle erreicht
while (!(Test-Connection 192.168.0.1 -Count 1 -quiet)){
sleep(1)
}

# Aktuelles Netzwerkprofil wird auf "Privat" geändert 
$net = get-netconnectionprofile;Set-NetConnectionProfile -Name $net.Name -NetworkCategory Private


# Restartet Script bei Bedarf mit erhöhten Rechten
if(!(new-object System.Security.Principal.WindowsPrincipal([System.Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole(544)){start powershell -Verb runas -ArgumentList '-File',$MyInvocation.MyCommand.Definition;exit}  

# Liest aktuelles Netzwerkprofil aus
$currentprofile = (Get-NetConnectionProfile).Name

# Setzt "managed" Key im aktuellem Netzwerkprofil 
Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles' | ?{$_.GetValue('ProfileName') -eq $currentprofile} | %{Set-ItemProperty $_.PsPath -Name Managed -Value 1}  

So sollte es für euch klarer sein.
Member: Charismea
Solution Charismea Feb 16, 2022 at 12:14:14 (UTC)
Goto Top
Ich habe nun eine "andere" Lösung für das Problem gefunden:

# Dieser PowerShell Befehl entspricht dem gewohnten Pingbefehl (aus CMD) mit den vier Ping-Versuchen
Test-Connection -ComputerName 192.168.80.1

# Hier wird nur das Ergebnis der Abfrage ("erreicht"/"nicht erreicht") ausgewertet 
if (Test-Connection -ComputerName 192.168.80.1 -Quiet) {
   write-host Ziel IP erreicht, Host befindet sich in einem DCS/CWP-Network

    # Aktuelles Netzwerkprofil wird auf "Privat" geändert 
    $net = get-netconnectionprofile;Set-NetConnectionProfile -Name $net.Name -NetworkCategory Private

    # Restartet Script bei Bedarf mit erhöhten Rechten
    if(!(new-object System.Security.Principal.WindowsPrincipal([System.Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole(544)){start powershell -Verb runas -ArgumentList '-File',$MyInvocation.MyCommand.Definition;exit}  

    # Liest aktuelles Netzwerkprofil aus
    $currentprofile = (Get-NetConnectionProfile).Name

    # Setzt "managed" Key im aktuellem Netzwerkprofil 
    Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles' | ?{$_.GetValue('ProfileName') -eq $currentprofile} | %{Set-ItemProperty $_.PsPath -Name Managed -Value 1}  

}

# Hier wird nur das Ergebnis der Abfrage ("erreicht"/"nicht erreicht") ausgewertet 
if (-not (Test-Connection -ComputerName 192.168.80.1 -Quiet)) {
   write-host Ziel IP nicht erreichbar, Host befindet sich nicht in einem DCS/CWP-Network

   # Beende das Script
   exit

}

Ich danke euch für die vielen Inputs.
Mitglied: 1915348599
1915348599 Feb 16, 2022 updated at 16:34:07 (UTC)
Goto Top
# Restartet Script bei Bedarf mit erhöhten Rechten
if(!(new-object System.Security.Principal.WindowsPrincipal([System.Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole(544)){start powershell -Verb runas -ArgumentList '-File',$MyInvocation.MyCommand.Definition;exit}
Das macht hier bei unbeaufsichtigtem Start keinen Sinn. Das ist nur nötig wenn man das Skript manuell mit einem User startet.

# Hier wird nur das Ergebnis der Abfrage ("erreicht"/"nicht erreicht") ausgewertet
Überflüssige doppelte Test-Connection Abfrage, pack das ganze in den "Else"-Teil der ersten IF-Abfrage, fertig.