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 Jun 19, 2020 um 11:23:26 Uhr
Titel von Rechtschreibfehlern befreit

Content-Key: 399859

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

Printed on: April 27, 2024 at 19:04 o'clock

Member: SlainteMhath
SlainteMhath Jan 30, 2019 updated at 12:09:17 (UTC)
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
Member: Daemmerung
Daemmerung Jan 30, 2019 at 12:32:04 (UTC)
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.
Member: thomas1972
thomas1972 Jan 30, 2019 at 15:28:17 (UTC)
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
Member: Daemmerung
Daemmerung Jan 30, 2019 at 15:36:42 (UTC)
Goto Top
Wie ermittelst du die betroffenen IP-Adressen? Liegen die in einer CSV-Datei bzw. in irgendeiner Datei? Fragt ihr die irgendwo ab?
Member: thomas1972
thomas1972 Jan 30, 2019 at 15:58:02 (UTC)
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)
Member: Daemmerung
Daemmerung Jan 30, 2019 updated at 16:28:15 (UTC)
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
Member: colinardo
colinardo Jan 30, 2019, updated at Jun 19, 2020 at 10:47:26 (UTC)
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
Member: thielm
thielm Apr 19, 2020 at 10:01:12 (UTC)
Goto Top
Gibt es auch eine Möglichkeit, das Ergebnis in eine Datei zu speichern?
Member: colinardo
colinardo Apr 19, 2020 updated at 12:08:01 (UTC)
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