thomas1972
Goto Top

Per Powershell mehrere IP-Adressen prüfen

Hallo zusammen,

ich bin selbst neu im Bereich Power Shell und habe folgendes Problem.
Ich möchte mehre IP Adresse auf Erreichbarkeit Prüfen und mir das Ergebnis anzeigen lassen.

$ping = Test-Connection xx.xx.xx.xx, xx.xx.xx.xx, xx.xx.xx.xx, xx.xx.xx.xx, xx.xx.xx.xx, xx.xx.xx.xx
 
foreach($p in $ping)
 { 
          if ($p -eq $false) 
              {
               Write-Host $p "nicht erreichbar!"  
              }
 
}

Leider weis ich nicht wie man eine "schleife" erstellt. bzw. die Variablen jeweils übergeben kann...
Kommentar vom Moderator tomolpi am 19.06.2020 um 13:23:26 Uhr
Titel von Rechtschreibfehlern befreit

Content-ID: 399859

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

Ausgedruckt am: 15.11.2024 um 05:11 Uhr

SlainteMhath
SlainteMhath 30.01.2019 aktualisiert um 13:09:17 Uhr
Goto Top
Moin,

Denkanstoß:
$hosts=xx.xx.xx.xx, xx.xx.xx.xx, xx.xx.xx.xx, xx.xx.xx.xx, xx.xx.xx.xx, xx.xx.xx.xx
foreach($ip in $hosts) {
    try {
        Test-Connection $ip 
    } catch {
        write-host $ip "nicht erreichbar"  
    }
}
Aus dem Kopf und ohne Gewähr. I-wo fehlen da sicher ein paar Quotes und Parameter face-smile

lg,
Slainte
Daemmerung
Daemmerung 30.01.2019 um 13:32:04 Uhr
Goto Top
Aus welcher Quelle kommen den ndie IP-Adressen? Vielleicht können wir dann besser auf die Fragestellung eingehen bzw. dir aufzeigen, wie man die Quelle verarbeitet.

Ansonsten können dann noch die CmdLets Import-CSV und Get-Content hilfreich sein.
thomas1972
thomas1972 30.01.2019 um 16:28:17 Uhr
Goto Top
Hallo,

es sind immer unterschiedliche IP Adresse, welche entweder hinzukommen oder weg fallen. daher kann ich auch auf keine Lokale Quelle zurück greifen. Ziel ist es eigentlich über eine Schleife X IP Adressen der reihe nach abzufragen und das Ergebnis ( erreichbar/nicht erreichbar) auszugeben

Gruß
Thomas
Daemmerung
Daemmerung 30.01.2019 um 16:36:42 Uhr
Goto Top
Wie ermittelst du die betroffenen IP-Adressen? Liegen die in einer CSV-Datei bzw. in irgendeiner Datei? Fragt ihr die irgendwo ab?
thomas1972
thomas1972 30.01.2019 um 16:58:02 Uhr
Goto Top
die hat man mir genannt. in der Regel sind die fest vorgegeben.
Es ist eben müßig bei Problemen immer ein ping manuell über alle Adressen einzeln laufen zu lassen.
da dachte ich es ist einfacher über die Power Shell ( Skript)
Daemmerung
Daemmerung 30.01.2019 aktualisiert um 17:28:15 Uhr
Goto Top
Hey,

dann ist es am einfachsten, wenn du dir eine CSV-Datei anlegst und diese abarbeitest. Das Ganze könnte wie folgt aussehen:

CSV-File:
IP
8.8.8.8
4.4.4.4
85.22.120.12

PS-Code:
$hosts = Import-CSV -path <PATH> -encoding utf8 -delimiter ';'  
$resource_unavailable = @()

Foreach($host IN $hosts)
{
	try
	{
		Test-Connection $host.ip
	}
	catch
	{
		$resource_unavailable += $host.ip
	}
}

Write-Host "Folgende IPs sind nicht erreichbar"  
$resource_unavailable


Vielleicht kannst du damit etwas anfangen.

Viele Grüße und viel Erfolg
Toni
colinardo
Lösung colinardo 30.01.2019, aktualisiert am 19.06.2020 um 12:47:26 Uhr
Goto Top
Servus,
das einfachste ist ja wie oben schon geschrieben wurde, simple Foreach-Schleife über die Hosts
'x.x.x.x','x.x.x.x' | %{  
    if (Test-Connection $_ -Quiet -Count 1){
        write-host "$_ ist online." -F Green  
    }else{
        write-host "$_ ist offline" -F Yellow  
    }
}
Aber Test-Connection ist sowas von lahm besonders wenn es um viele Hosts handelt, kann das ziemlich nerven. Ich nutze, wenn mit Powershell, einen Workflow der mehrere Adressen per Threading parallel prüft.

Hier für einzelne Computer.
$computers = 'x.x.x.x','x.x.x.x'  

if ($PSVersionTable.PSVersion.Major -lt 4){write-host "ERROR: Minimum Powershell Version 4.0 is required!" -F Yellow; return}    

workflow Fast-PingComputers {
param(
    [parameter(mandatory=$true)][string[]]$computers,
    [parameter(mandatory=$false)][int]$timeout = 500,
    [parameter(mandatory=$false)][int]$throttlelimit = 5
)
    
   function Send-Ping {
        param([string]$device,[int]$delay)
        $ping = New-Object System.Net.NetworkInformation.Ping
        try{
            if($ping.Send($device,$delay).Status -ne "Success"){  
                return $false
            }else{
                return $true
            }
        }catch{
            return $false
        }finally{
            $ping.Dispose()
        }
    }
    
    foreach -parallel -throttle $throttlelimit ($c in $computers){
        $status = Send-Ping $c $timeout
        [pscustomobject]@{Name=$c;PingStatus=$status}
    }
}

$result = Fast-PingComputers $computers -timeout 100 -throttlelimit 5 | sort {[int64]$_.Name.replace('.','')}  
$online = $result | ?{$_.PingStatus}
$offline = $result | ?{!$_.PingStatus}

write-host "Online:" -F Green  
$online | ft Name,PingStatus -AutoSize
write-host "Offline:" -F Yellow  
$Offline | ft Name,PingStatus -AutoSize
Wenn man stattdessen ein ganzes Subnetz schnell scannen möchte geht auch das viel viel schneller mit parallel processing, bei dem man ganz einfach das Subnetz mit Maske angeben kann:
$net = "192.168.1.0/24"  

if ($PSVersionTable.PSVersion.Major -lt 4){write-host "ERROR: Minimum Powershell Version 4.0 is required!" -F Yellow; return}    

workflow Fast-PingNetRange {
param(
    [parameter(mandatory=$true)][ValidateScript({$_ -match '(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/([1-2][0-9]|3[0-2]|[0-9])'})][string]$network,  
    [parameter(mandatory=$false)][int]$timeout = 500,
    [parameter(mandatory=$false)][int]$throttlelimit = 5
)
    
    function Send-Ping {
        param([string]$device,[int]$delay)
        $ping = New-Object System.Net.NetworkInformation.Ping
        try{
            if($ping.Send($device,$delay).Status -ne "Success"){  
                return $false
            }else{
                return $true
            }
        }catch{
            return $false
        }finally{
            $ping.Dispose()
        }
    }

    function Get-NetworkRange {
    param(
        [parameter(mandatory=$true)][String]$IP, 
        [parameter(mandatory=$true)][String]$Mask
    )
        try{
            if (!$Mask.Contains('.')) {  
                $Mask = [Convert]::ToUInt32((("1" * $Mask).PadRight(32, "0")), 2)  
            }
            $toDecimalIP = {
                param([Net.IPAddress]$ip)
                $i = 3; $decip = 0;
                $ip.GetAddressBytes() | %{ $decip += $_ * [Math]::Pow(256, $i); $i-- }
                return [UInt32]$decip
            }

            $dIP = & $toDecimalIP $IP
            $dMask = & $toDecimalIP $Mask
  
            $Network = $dIP -band $dMask
            $Broadcast = $dIP -bor ((-bnot $dMask) -band [UInt32]::MaxValue)

            for ($i = $($Network + 1); $i -lt $Broadcast; $i++){
                $ipa = [UInt32]$i
                [String]::Join('.', $(for ($j = 3; $j -gt -1; $j--) {  
                    $Remainder = $ipa % [Math]::Pow(256, $j)
                    ($ipa - $Remainder) / [Math]::Pow(256, $j)
                    $ipa = $Remainder
                    }))
            }
        }catch{
            Write-Error $_.Exception.Message
        }
    }
    
    foreach -parallel -throttle $throttlelimit ($c in (Get-NetworkRange -IP $network.split('/') -Mask $network.split('/')[1])){  
        $status = Send-Ping $c $timeout
        [pscustomobject]@{Name=$c;PingStatus=$status}
    }
}


$result = Fast-PingNetRange -network $net -timeout 100 -throttlelimit 5

$resultGrouped = $result | sort {[int64]($_.Name.replace('.',''))} | group PingStatus  
$online = $resultGrouped| ?{$_.Name -eq $true} | %{$_.Group.Name}
$offline = $resultGrouped | ?{$_.Name -eq $false} | %{$_.Group.Name}

write-host "Online:" -F Green  
$online
write-host "Offline:" -F Yellow  
$offline

Schönen Abend Kollegen.
Grüße Uwe
thielm
thielm 19.04.2020 um 12:01:12 Uhr
Goto Top
Gibt es auch eine Möglichkeit, das Ergebnis in eine Datei zu speichern?
colinardo
colinardo 19.04.2020 aktualisiert um 14:08:01 Uhr
Goto Top
Zitat von @thielm:

Gibt es auch eine Möglichkeit, das Ergebnis in eine Datei zu speichern?
$result | export-csv 'e:\ergebnis.csv' -delimiter ";" -NoType -Encoding UTF8  
Export-Csv
Set-Content
out-file