Testen Sie Netzwerkports schneller mit PowerShell

13359
Iszi

In Windows 8.1 ist das Test-NetConnectionCmdlet hilfreich, um den Status eines Netzwerkports auf einem Remote-System zu überprüfen. Es kann jedoch manchmal unnötig langsam sein. Ich würde gerne wissen, ob es einige Optionen gibt, die ich anpassen könnte, oder einen alternativen PowerShell-Befehl, den ich verwenden könnte, um diesen Prozess zu beschleunigen.

Test-NetConnectionEs kann ungefähr 10 Sekunden dauern, bis Ergebnisse zurückgegeben werden, wenn ein Remote-System nicht reagiert. Wenn ein Port angegeben wird, werden zwei Verbindungstests ausgeführt, die jeweils etwa 5 Sekunden dauern, um das Zeitlimit festzulegen. Der erste Test ist eine grundlegende ICMP-Echoprüfung. Dies führt zu einer Zeitüberschreitung, wenn das System offline ist oder wenn es (oder eine dazwischen liegende Infrastruktur) so konfiguriert ist, dass es ICMP-Echoanforderungen blockiert oder nicht antwortet. Der zweite Test ist die tatsächliche Überprüfung des angegebenen Ports. Dies führt zu einer Zeitüberschreitung, wenn das System offline ist oder wenn sich auf dem Pfad eine Firewall befindet, die den Port blockiert.

In meinem aktuellen Anwendungsfall befindet sich das entfernte System nur zwei Hops entfernt auf einer zuverlässigen Gigabit-Ethernet-Verbindung. Daher ist ein Timeout von fünf Sekunden für jede Anforderung ziemlich übertrieben - ich könnte wahrscheinlich mit einem Timeout von 30 ms oder weniger immer noch zuverlässige Ergebnisse erzielen! Darüber hinaus reagiert das System auf ICMP-Echo nicht, auch wenn es online ist und alle anderen Dienste zur Verfügung stehen. Es wäre also großartig, wenn ich ganz ohne den ICMP-Echo-Test auskommen könnte und das Zeitlimit für den TCP-Verbindungstest verkürzen könnte, um meine Skripte, die Test-NetConnectionfür diesen Zweck verwendet werden, zu beschleunigen .

Gibt Test-NetConnectiones Optionen zum Ändern dieser Verhaltensweisen? (Ich habe die ausführliche Hilfedatei gelesen und die Antwort scheint nein zu sein - aber ich würde gerne erfahren, dass etwas fehlt, was ich vermisst habe.) Oder gibt es eine andere Möglichkeit, mit PowerShell dieselben Überprüfungen durchzuführen, aber schneller

Aus verschiedenen Gründen ziehe ich es vor, meine Skripte auf die Nutzung der im Betriebssystem integrierten Funktionen zu beschränken, wo immer dies möglich ist. Es wird davon ausgegangen, dass es sich bei der Umgebung um eine neue Version von Windows 8.1 handelt, auf die alle entsprechenden Windows-Updates angewendet werden. Drittanbieter-Tools sind keine Option.

4
Zugehörige Frage: [So prüfen Sie offene Ports mit Powershell?] (Http://stackoverflow.com/q/19213830) Einige Artikel, die ebenfalls nützlich sein könnten: [Powershell - Testen Sie TCP-Ports auf Remote-Servern] (http: // noamwajnman.wordpress.com/2014/04/02/powershell-test-tcp-ports-on-remote-servers/), [Auf offene TCP-Ports mit PowerShell prüfen] (http://www.powershelladmin.com/wiki/ Check_for_open_TCP_ports_using_PowerShell), [Testen von TCP-Ports mit einer möglichen Header-Antwort] (http://learn-powershell.net/2014/04/18/testing-tcp-ports-with-a-possible-header-response/) and31415 vor 9 Jahren 0

4 Antworten auf die Frage

3
Jan Doggen

Sie können dies zum Testen der Verbindung verwenden - aus dem PowerShell Code Repository (Autor 'BSonPosh') :

"Test-Port erstellt eine TCP-Verbindung zum angegebenen Port. Standardmäßig stellt er eine Verbindung mit Port 135 mit einem Timeout von 3 Sekunden her."

Param([string]$srv,$port=135,$timeout=3000,[switch]$verbose)  # Test-Port.ps1 # Does a TCP connection on specified port (135 by default)  $ErrorActionPreference = "SilentlyContinue"  # Create TCP Client $tcpclient = new-Object system.Net.Sockets.TcpClient  # Tell TCP Client to connect to machine on Port $iar = $tcpclient.BeginConnect($srv,$port,$null,$null)  # Set the wait time $wait = $iar.AsyncWaitHandle.WaitOne($timeout,$false)  # Check to see if the connection is done if(!$wait) { # Close the connection and report timeout $tcpclient.Close() if($verbose) Return $false } else { # Close the connection and report the error if there is one $error.Clear() $tcpclient.EndConnect($iar) | out-Null if(!$?);$failed = $true} $tcpclient.Close() }  # Return $true if connection Establish else $False if($failed)else 

Sie können zu dieser Repository-Seite für Folgemaßnahmen gehen (diese Antwort ist bereits ein zu großer Kopierauftrag).

2
js2010

Sehr einfach (Timeout 100 ms):

function testport ($hostname='yahoo.com',$port=80,$timeout=100) { $requestCallback = $state = $null $client = New-Object System.Net.Sockets.TcpClient $beginConnect = $client.BeginConnect($hostname,$port,$requestCallback,$state) Start-Sleep -milli $timeOut if ($client.Connected) { $open = $true } else { $open = $false } $client.Close() [pscustomobject]@ }  testport  hostname port open -------- ---- ---- yahoo.com 80 True 
1
laurent

Ein noch schnellerer Weg könnte sein:

param($ip,$port) New-Object System.Net.Sockets.TCPClient -ArgumentList $ip, $port 

Das Ergebnis wäre:

Client : System.Net.Sockets.Socket Available : 0 Connected : True ExclusiveAddressUse : False ReceiveBufferSize : 65536 SendBufferSize : 65536 ReceiveTimeout : 0 SendTimeout : 0 LingerState : System.Net.Sockets.LingerOption NoDelay : False 

Der interessting Wert ist "Connected"

edit: ein weiterer Grund: Test-NetConnection funktioniert nur von Powershell v5 (wenn ich mich recht erinnere), während diese Lösung von v2 funktioniert :)

Dieser Weg dauert viel länger, wenn der Host nicht erreichbar ist als die Lösung von Jan. Mark Allison vor 6 Jahren 0
Funktioniert auch auf PS v4.0 Janis Veinbergs vor 6 Jahren 0
0
YetAnotherRandomUser

Ich hatte nach einem superschnellen Weg gesucht, nach vielen IPs zu suchen, und stolperte unter anderem über diese Frage.

Schließlich fand ich ein Skript, das sich leicht in das integrieren ließ, was ich wollte. Der Typ nennt es Fast Ping Sweep Asynchron .

Obwohl ich ein Power Shell n00b bin, konnte ich seine Ausgabe pfeifen und dann die Ausgabe so ändern, dass sie nur das enthält, was ich wollte. Ich bin auf andere Skripte gestoßen, konnte sie jedoch nicht entschlüsseln, um sie für meine Zwecke zu modifizieren.

Ich bin nicht sicher, welche Version Power Shell dies erfordert, aber es funktioniert auf v4 und v5.

Ich habe die meisten des Powershell-IP-Scanners gesehen, ping-sweeping-Skripts, aber keines von ihnen verwendet die PingASync-Methode Dieser Ansatz kann s dauern

function Global:Ping-IPRange { <# .SYNOPSIS Sends ICMP echo request packets to a range of IPv4 addresses between two given addresses.  .DESCRIPTION This function lets you sends ICMP echo request packets ("pings") to  a range of IPv4 addresses using an asynchronous method.  Therefore this technique is very fast but comes with a warning. Ping sweeping a large subnet or network with many swithes may result in  a peak of broadcast traffic. Use the -Interval parameter to adjust the time between each ping request. For example, an interval of 60 milliseconds is suitable for wireless networks. The RawOutput parameter switches the output to an unformated [System.Net.NetworkInformation.PingReply[]].  .INPUTS None You cannot pipe input to this funcion.  .OUTPUTS The function only returns output from successful pings.  Type: System.Net.NetworkInformation.PingReply  The RawOutput parameter switches the output to an unformated [System.Net.NetworkInformation.PingReply[]].  .NOTES Author : G.A.F.F. Jakobs Created : August 30, 2014 Version : 6  .EXAMPLE Ping-IPRange -StartAddress 192.168.1.1 -EndAddress 192.168.1.254 -Interval 20  IPAddress Bytes Ttl ResponseTime --------- ----- --- ------------ 192.168.1.41 32 64 371 192.168.1.57 32 128 0 192.168.1.64 32 128 1 192.168.1.63 32 64 88 192.168.1.254 32 64 0  In this example all the ip addresses between 192.168.1.1 and 192.168.1.254 are pinged using  a 20 millisecond interval between each request. All the addresses that reply the ping request are listed.  .LINK http://gallery.technet.microsoft.com/Fast-asynchronous-ping-IP-d0a5cf0e  #> [CmdletBinding(ConfirmImpact='Low')] Param( [parameter(Mandatory = $true, Position = 0)] [System.Net.IPAddress]$StartAddress, [parameter(Mandatory = $true, Position = 1)] [System.Net.IPAddress]$EndAddress, [int]$Interval = 30, [Switch]$RawOutput = $false )  $timeout = 2000  function New-Range ($start, $end) {  [byte[]]$BySt = $start.GetAddressBytes() [Array]::Reverse($BySt) [byte[]]$ByEn = $end.GetAddressBytes() [Array]::Reverse($ByEn) $i1 = [System.BitConverter]::ToUInt32($BySt,0) $i2 = [System.BitConverter]::ToUInt32($ByEn,0) for($x = $i1;$x -le $i2;$x++){ $ip = ([System.Net.IPAddress]$x).GetAddressBytes() [Array]::Reverse($ip) [System.Net.IPAddress]::Parse($($ip -join '.')) } }  $IPrange = New-Range $StartAddress $EndAddress  $IpTotal = $IPrange.Count  Get-Event -SourceIdentifier "ID-Ping*" | Remove-Event Get-EventSubscriber -SourceIdentifier "ID-Ping*" | Unregister-Event  $IPrange | foreach{  [string]$VarName = "Ping_" + $_.Address  New-Variable -Name $VarName -Value (New-Object System.Net.NetworkInformation.Ping)  Register-ObjectEvent -InputObject (Get-Variable $VarName -ValueOnly) -EventName PingCompleted -SourceIdentifier "ID-$VarName"  (Get-Variable $VarName -ValueOnly).SendAsync($_,$timeout,$VarName)  Remove-Variable $VarName  try{  $pending = (Get-Event -SourceIdentifier "ID-Ping*").Count  }catch [System.InvalidOperationException]{}  $index = [array]::indexof($IPrange,$_)  Write-Progress -Activity "Sending ping to" -Id 1 -status $_.IPAddressToString -PercentComplete (($index / $IpTotal) * 100)  Write-Progress -Activity "ICMP requests pending" -Id 2 -ParentId 1 -Status ($index - $pending) -PercentComplete (($index - $pending)/$IpTotal * 100)  Start-Sleep -Milliseconds $Interval }  Write-Progress -Activity "Done sending ping requests" -Id 1 -Status 'Waiting' -PercentComplete 100   While($pending -lt $IpTotal){  Wait-Event -SourceIdentifier "ID-Ping*" | Out-Null  Start-Sleep -Milliseconds 10  $pending = (Get-Event -SourceIdentifier "ID-Ping*").Count  Write-Progress -Activity "ICMP requests pending" -Id 2 -ParentId 1 -Status ($IpTotal - $pending) -PercentComplete (($IpTotal - $pending)/$IpTotal * 100) }  if($RawOutput){  $Reply = Get-Event -SourceIdentifier "ID-Ping*" | ForEach {  If($_.SourceEventArgs.Reply.Status -eq "Success"){ $_.SourceEventArgs.Reply } Unregister-Event $_.SourceIdentifier Remove-Event $_.SourceIdentifier }  }else{  $Reply = Get-Event -SourceIdentifier "ID-Ping*" | ForEach {  If($_.SourceEventArgs.Reply.Status -eq "Success"){ $_.SourceEventArgs.Reply | select @{ Name="IPAddress" ; Expression={$_.Address}}, @}, @}, @} } Unregister-Event $_.SourceIdentifier Remove-Event $_.SourceIdentifier } } if($Reply -eq $Null){ Write-Verbose "Ping-IPrange : No ip address responded" -Verbose }  return $Reply }