
In Windows 8.1 Test-NetConnection
ist das Cmdlet nützlich, um den Status eines Netzwerkports auf einem Remotesystem zu überprüfen. Es kann jedoch manchmal unnötig langsam sein. Ich würde gerne wissen, ob es einige Optionen gibt, die ich optimieren könnte, oder einen alternativen PowerShell-Befehl, den ich verwenden könnte, um diesen Vorgang zu beschleunigen.
Test-NetConnection
kann etwa 10 Sekunden dauern, bis Ergebnisse zurückgegeben werden, wenn ein Remote-System nicht antwortet. Immer wenn ein Port angegeben wird, werden zwei Verbindungstests ausgeführt, die jeweils etwa 5 Sekunden dauern und dann ablaufen. Der erste Test ist eine einfache ICMP-Echoprüfung. Diese wird ablaufen, wenn das System offline ist oder wenn es (oder eine dazwischenliegende Infrastruktur) so konfiguriert ist, dass es ICMP-Echoanforderungen blockiert oder nicht beantwortet. Der zweite Test ist die eigentliche Prüfung des angegebenen Ports. Diese wird ablaufen, wenn das System offline ist oder wenn sich entlang des Pfads eine Firewall befindet, die den Port blockiert.
In meinem aktuellen Anwendungsfall ist das Remote-System nur zwei Hops entfernt und verfügt über eine zuverlässige Gigabit-Ethernet-Verbindung. Ein Timeout von fünf Sekunden für jede Anfrage ist also ziemlich übertrieben – ich könnte wahrscheinlich immer noch zuverlässige Ergebnisse mit einem Timeout von 30 ms oder weniger erzielen! Darüber hinaus ist bekannt, dass das System nicht auf ICMP-Echo reagiert, obwohl es online ist und alle anderen Dienste verfügbar sind. Daher wäre es großartig, wenn ich ganz auf den ICMP-Echotest verzichten und das Timeout für den TCP-Verbindungstest reduzieren könnte, um meine Skripte zu beschleunigen, die ich Test-NetConnection
für diesen Zweck verwende.
Gibt Test-NetConnection
es Optionen zum Ändern dieser Verhaltensweisen? (Ich habe die ausführliche Hilfedatei gelesen und die Antwort scheint „Nein“ zu sein – würde mich aber freuen, wenn man mir sagt, dass ich etwas übersehen habe.) Oder gibt es eine andere Möglichkeit, mit PowerShell dieselben Prüfungen schneller auszuführen?
Aus verschiedenen Gründen ziehe ich es vor, meine Skripte möglichst auf die Nutzung der im Betriebssystem integrierten Funktionen zu beschränken. Gehen wir davon aus, dass es sich bei der Umgebung um eine neue Version von Windows 8.1 handelt, auf der alle entsprechenden Windows-Updates installiert sind und Tools von Drittanbietern keine Option sind.
Antwort1
Ganz 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]@{hostname=$hostname;port=$port;open=$open}
}
testport
hostname port open
-------- ---- ----
yahoo.com 80 True
Antwort2
Der kürzeste Weg zum Testen eines TCP-Ports, den ich gesehen habe, ist:
(New-Object System.Net.Sockets.TcpClient).ConnectAsync("google.com", 80).Wait(100)
oder
[System.Net.Sockets.TcpClient]::new().ConnectAsync("google.com", 80).Wait(100)
Die Wartezeit beträgt ms. Dies ist eine alte, mit PowerShell 2.0 kompatible Methode.
Antwort3
Damit können Sie die Verbindung testen -Entnommen aus demPowerShell-Code-Repository(Autor „BSonPosh“):
„Test-Port erstellt eine TCP-Verbindung zum angegebenen Port. Standardmäßig wird eine Verbindung zu Port 135 mit einem Timeout von 3 Sekunden hergestellt.“
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){Write-Host "Connection Timeout"}
Return $false
}
else
{
# Close the connection and report the error if there is one
$error.Clear()
$tcpclient.EndConnect($iar) | out-Null
if(!$?){if($verbose){write-host $error[0]};$failed = $true}
$tcpclient.Close()
}
# Return $true if connection Establish else $False
if($failed){return $false}else{return $true}
Sie können für weitere Informationen auf diese Repository-Seite gehen (diese Antwort ist bereits zu sehr Kopierarbeit)
Antwort4
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 interessante Wert ist „Verbunden“
bearbeiten: noch ein Grund: Test-NetConnection funktioniert nur ab Powershell v5 (wenn ich mich richtig erinnere), während diese Lösung ab v2 funktioniert :)