Home > Windows にまつわる e.t.c.

PowerShell で特定 TCP ポートが開いているか確認する


特定 TCP ポートが開いているかを確認するには telnet でポート番号を指定して接続できるか確認するのですが、PowerShell スクリプトだとこの方法は使えません。

Windows 8.1 / Windows Server 2012 R2 以降であれば、Test-NetConnection で確認することができます

Test-NetConnection [ターゲット] -Port [ポート番号]

 

WinRM ポート(TCP/5985)が開いているかを確認する場合は、以下のようにします(TcpTestSucceeded を見ます)

PS C:\> Test-NetConnection dc01 -Port 5985


ComputerName           : dc01
RemoteAddress          : 2400:400e:400::dc01
RemotePort             : 5985
InterfaceAlias         : Host
SourceAddress          : 2400:400e:400:0:7143:c7df:5480:3ecb
PingSucceeded          : True
PingReplyDetails (RTT) : 2 ms
TcpTestSucceeded       : True

 

単純に True/False を得るのであれば、-InformationLevel Quiet オプションを指定します。

 

 

テスト中に緑帯で表示される PowerShell 通知が表示されるのがうっとうしい場合は、特殊変数の $ProgressPreference に SilentlyContinue をセットすると緑帯が表示されなくなります。

$ProgressPreference="SilentlyContinue"

 

ちょっと残念なのは、Test-NetConnection は ping 確認する仕様なので、ICMP を閉じているホストがターゲットだとしばらく待たされます。

 

.NET Framework でポートが開いているか確認する

Test-NetConnection が使えないバージョンの場合や ping チェックを嫌う場合は .NET Framework の System.Net.Sockets を使って確認用の関数を自作します。

##########################################################################
# ポート確認
##########################################################################
function QueryTCPPort($Terget, $Port){
    # エラー表示を抑制する
    $SaveErrorActionPreference = $ErrorActionPreference
    $ErrorActionPreference = "SilentlyContinue"

    # アセンブリがロードされていなかったらロードする
    $Lib = "System.Net"
    if(([Appdomain]::CurrentDomain.GetAssemblies() | ?{$_.GetName().Name -eq $Lib}) -eq $null){
        [void][System.Reflection.Assembly]::LoadWithPartialName($Lib)
    }

    # ポートに接続する
    $TCPSocket = New-Object System.Net.Sockets.TcpClient($Terget, $Port)
    
    if( $TCPSocket -ne $null ){
        # 接続できた
        $ReturnStatus = $True
        $TCPSocket.Close()
    }
    else{
        # 接続できなかった
        $ReturnStatus = $False
    }
    
    # エラー表示を戻す
    $ErrorActionPreference = $SaveErrorActionPreference

    Return $ReturnStatus
}

 

PS C:\> QueryTCPPort 192.168.33.50 5985
True

 

タイムアウト対策

この関数もポートが開いているときはすぐにリターンしてくれるのですが、ポートが開いていない場合はタイムアウトするまで待たされてしまいます。

タイムアウトするまで待てない場合は、Start-Job でバックグラウンドジョブにして、所定時間までに完了しなかった時にはポートが開いていないと判断します。

$TimeOut = 1
$IPAddress = "192.168.33.50"
$Port = 22
$JobStatus = Start-Job -ScriptBlock ${function:QueryTCPPort} -ArgumentList $IPAddress, $Port

Wait-Job $JobStatus -Timeout $TimeOut
if( $JobStatus.State -eq "Completed"){
    $JobReturn = Receive-Job $JobStatus
}
else{
    # タイムアウト
    $JobReturn = $false
}
echo $JobReturn

 

 

 

back.gif (1980 バイト)

home.gif (1907 バイト)

Copyright © MURA All rights reserved.