PowerShell でネットワーク ポートをより速くテストする

PowerShell でネットワーク ポートをより速くテストする

Windows 8.1 では、このTest-NetConnectionコマンドレットはリモート システムのネットワーク ポートの状態を確認するのに便利です。ただし、場合によっては、不必要に遅くなることがあります。このプロセスを高速化するために、調整できるオプションや、使用できる代替の PowerShell コマンドがあるかどうかを知りたいです。

Test-NetConnectionリモート システムが応答しない場合、結果を返すまでに約 10 秒かかることがあります。ポートが指定されると、2 つの接続テストが実行され、それぞれタイムアウトするまでに約 5 秒かかります。最初のテストは基本的な ICMP エコー チェックです。システムがオフラインの場合、またはシステム (または介在するインフラストラクチャ) が ICMP エコー要求をブロックするか応答しないように構成されている場合は、タイムアウトになります。2 番目のテストは、指定されたポートに対する実際のチェックです。システムがオフラインの場合、またはパスにポートをブロックしているファイアウォールがある場合、タイムアウトになります。

私の現在の使用例では、リモート システムは信頼性の高いギガビット イーサネット接続でわずか 2 ホップしか離れていません。したがって、リクエストの 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 接続を作成します。デフォルトでは、3 秒のタイムアウトでポート 135 に接続します。」

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

興味深い値は「接続」です

編集: もう 1 つの理由: Test-NetConnection は Powershell v5 からのみ機能します (正しく覚えていれば)。一方、このソリューションは v2 から機能します :)

関連情報