使用 PowerShell 更快測試網路端口

使用 PowerShell 更快測試網路端口

在 Windows 8.1 中,Test-NetConnectioncmdlet 對於檢查遠端系統上網路連接埠的狀態非常有用。然而,有時它可能會不必要地緩慢。我想知道是否有一些我可以調整的選項,或者我可以使用替代的 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 :)

相關內容