
在 Windows 8.1 中,Test-NetConnection
cmdlet 對於檢查遠端系統上網路連接埠的狀態非常有用。然而,有時它可能會不必要地緩慢。我想知道是否有一些我可以調整的選項,或者我可以使用替代的 PowerShell 命令,以使此過程更快。
Test-NetConnection
如果遠端系統沒有回應,可能需要大約 10 秒才能傳回結果。每當指定連接埠時,它都會執行兩次連接測試,每次大約需要 5 秒鐘才會逾時。第一個測試是基本的 ICMP 回顯檢查。如果系統離線,或系統(或任何干預基礎架構)配置為阻止或不回應 ICMP 回顯請求,則此操作將會逾時。如果系統離線,或路徑上有防火牆阻止端口,則此操作將會逾時。
在我目前的用例中,遠端系統距離可靠的千兆位元乙太網路連接僅兩跳。因此,任何請求的 5 秒超時都相當過大 - 我可能仍然可以通過 30 毫秒或更短的超時獲得可靠的結果!此外,已知該系統對 ICMP 回顯沒有回應,即使它可能在線並且具有所有其他可用服務。因此,如果我可以完全不用 ICMP 回顯測試,並減少 TCP 連線測試的逾時,以加快用於Test-NetConnection
此目的的腳本,那就太好了。
是否Test-NetConnection
可以選擇改變這些行為? (我已經閱讀了詳細的幫助文件,答案似乎是否定的 - 但我很高興被告知我錯過了一些東西。)或者是否有另一種方法可以使用 PowerShell 來運行相同的檢查,但更快?
由於各種原因,我更喜歡盡可能將我的腳本限制為使用作業系統內建的功能。假設環境是全新的 Windows 8.1 版本,應用了所有適當的 Windows 更新,並且不支援第三方工具。
答案1
非常基本(超時 100 毫秒):
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
答案2
我見過的測試 TCP 連接埠的最短方法是:
(New-Object System.Net.Sockets.TcpClient).ConnectAsync("google.com", 80).Wait(100)
或者
[System.Net.Sockets.TcpClient]::new().ConnectAsync("google.com", 80).Wait(100)
等待時間以毫秒為單位。這是舊的 PowerShell 2.0 相容方法。
答案3
您可以用它來測試連接 -取自PowerShell 程式碼儲存庫(作者“BSonPosh”):
“Test-Port 建立到指定連接埠的 TCP 連線。預設情況下,它連接到連接埠 135,逾時為 3 秒。”
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}
您可以前往該儲存庫頁面進行後續操作(這個答案已經太多了複製工作)
答案4
更快的方法可能是:
param($ip,$port)
New-Object System.Net.Sockets.TCPClient -ArgumentList $ip, $port
結果是:
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
有趣的值是“已連接”
編輯:還有一個原因:Test-NetConnection 僅適用於 Powershell v5(如果我沒記錯的話),而此解決方案適用於 v2 :)