PowerShellを使って特定のポートが使用中かどうか確認する方法

PowerShellでポートを確認するときは、「自分のPCでその番号を待ち受けているプロセスがあるか」と「別のPCから接続先のポートまで通信できるか」を分けることが最重要です。ローカルのTCP待受はGet-NetTCPConnection、UDPのバインドはGet-NetUDPEndpoint、リモートのTCP到達性はTest-NetConnectionで読み取れます。「使用中」という言葉だけでは、待受中、接続済み、一時的な送信元ポート、ファイアウォールで遮断、サービス停止のどれか判断できません。変更前に対象PC、TCPまたはUDP、ローカルまたはリモート、ポート番号を明確にし、結果を状態とプロセスIDまで確認します。

目次

最初に決める4つの条件

  1. 調べるポート番号を決めます。例としてWebサーバーのTCP 443、RDPの既定TCP 3389などです。
  2. TCPかUDPかを製品の公式仕様で確認します。同じ番号でもTCPとUDPは別のエンドポイントです。
  3. 自分のPCの待受を調べるのか、別サーバーへの到達性を調べるのかを分けます。
  4. 接続先は正式なDNS名を使い、テスト時刻、実行元ネットワーク、VPNの有無も記録します。

たとえば「443番ポートが空いているか」という質問には二つの意味があります。サーバー上でアプリがTCP 443を待ち受けているかを知りたいならローカル接続テーブルを見ます。利用者PCからweb01.example.comのTCP 443へ届くかを知りたいなら、利用者PCからリモート到達性を確認します。前者が正常でも途中のネットワークで遮断されれば後者は失敗し、後者が成功しても期待したアプリが応答しているとは限りません。

ローカルのTCP待受を確認する

対象PC自身でTCP 443を確認する基本例は次のとおりです。これは接続テーブルを読むだけで、サービス、ファイアウォール、レジストリを変更しません。

Get-NetTCPConnection -LocalPort 443 -ErrorAction SilentlyContinue |
    Select-Object LocalAddress, LocalPort, RemoteAddress, RemotePort, State, OwningProcess

StateがListenなら、そのローカルアドレスとポートで着信接続を待っています。Establishedは既存の接続が成立している状態です。TimeWaitは終了したTCP接続を一定時間保持する状態で、新しいサーバーが待受中であることを意味しません。何も返らなければ、その時点で条件に一致するTCPエンドポイントがない可能性があります。権限や取得タイミングもあるため、期待するサービスの状態とイベントログを合わせて確認します。

LocalAddressの読み方

0.0.0.0はIPv4の複数インターフェースで待ち受けるワイルドカード、::はIPv6側のワイルドカードとして使われます。127.0.0.1または::1だけなら、通常は同じPC内からのループバック接続に限定され、別PCからは直接届きません。特定のNICのIPだけなら、そのアドレスに到着した通信だけが対象です。待受アドレスはアプリの設定であり、ファイアウォール許可を示す値ではありません。

複数行が返る理由

IPv4とIPv6、待受と確立済み接続、複数インターフェースがあると同じローカルポートで複数行が返ります。最初の1行だけを見ず、State、LocalAddress、OwningProcessを比較します。クライアント通信では、Windowsが一時的な送信元ポートを自動選択するため、「LocalPortがその番号」というだけでサーバー待受とは限りません。待受を探す場合は状態を明示して絞れます。

Get-NetTCPConnection -State Listen -LocalPort 443 |
    Select-Object LocalAddress, LocalPort, OwningProcess

OwningProcessからプロセス名を調べる

OwningProcessはプロセスIDです。次の例はTCP 443を待ち受ける行を取得し、そのIDに対応するプロセスを読み取ります。プロセスを終了する操作ではありません。

$listeners = Get-NetTCPConnection -State Listen -LocalPort 443
$listeners | ForEach-Object {
    $process = Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue
    [pscustomobject]@{
        LocalAddress = $_.LocalAddress
        LocalPort    = $_.LocalPort
        ProcessId    = $_.OwningProcess
        ProcessName  = $process.ProcessName
    }
}

プロセス名がSystemやsvchostであっても、直ちに異常とは判断できません。HTTP.sysのようなカーネル側の仕組みや、複数サービスをホストするプロセスが関係する場合があります。期待しないプロセスを見つけても、PID指定で強制終了すると他サービスや利用者通信を止める可能性があります。実行ファイルの署名、サービスとの対応、製品の構成、イベントログを管理者が確認してから対処します。

UDPはGet-NetUDPEndpointで別に確認する

UDPにはTCPのListenやEstablishedと同じ接続状態がありません。UDP 53などのローカルバインドを調べる場合は次のようにします。

Get-NetUDPEndpoint -LocalPort 53 -ErrorAction SilentlyContinue |
    Select-Object LocalAddress, LocalPort, OwningProcess

行が返れば、その時点でプロセスがUDPエンドポイントをバインドしています。ただしUDPには接続確立のハンドシェイクがないため、エンドポイントが見えるだけで、アプリが要求へ正しく応答することやネットワーク越しに届くことは証明できません。DNSなら名前解決、NTPなら時刻同期など、対象プロトコルに合った公式クライアントとサーバーログで最終確認します。

リモートTCPポートへの到達性を確認する

利用者PCからサーバーのTCP 443へ届くかを確認する例です。web01.example.comは実際の正式な接続先名へ置き換えます。

Test-NetConnection -ComputerName web01.example.com -Port 443 -InformationLevel Detailed

主に見る値はComputerName、RemoteAddress、RemotePort、InterfaceAlias、SourceAddress、TcpTestSucceededです。TcpTestSucceededがTrueなら、実行元から解決されたアドレスのTCPポートまで接続を確立できたことを示します。Webサイトの証明書、HTTP応答、アプリ認証、データベースログインまで成功したとは限りません。アプリ層はブラウザーや製品の公式クライアントで別に確認します。

Falseの場合も、すぐに「ファイアウォールが原因」とは断定できません。DNSが誤ったアドレスを返した、VPN経路がない、サーバーが停止、サービスが待受していない、途中のACLで遮断、接続タイムアウトなどが考えられます。RemoteAddressとSourceAddressを記録し、サーバー側のローカル待受確認と同じ時刻で照合します。ファイアウォールを全停止して試すのではなく、管理者が必要な通信元、宛先、プロトコル、ポートに限定した規則を確認します。

名前とIPアドレスの結果が違う場合

DNS名で失敗し、IPアドレスで成功するなら、名前解決、DNSサフィックス、VPNのDNS配布、古いDNSレコードを調べます。ただしIPアドレスを恒久的な接続先へ変えると、TLS証明書の名前検証やKerberos認証が成立しなくなる場合があります。IPテストは切り分けに使い、正式なDNS名を修復します。

Resolve-DnsName web01.example.com
Test-NetConnection web01.example.com -Port 443
Test-NetConnection 192.0.2.20 -Port 443

上の192.0.2.20は文書用の例示アドレスです。実環境では管理者が確認した接続先IPを使います。複数のAまたはAAAAレコードがある負荷分散構成では、実行ごとに別アドレスへ接続する場合があります。失敗したRemoteAddressを記録し、全バックエンドの状態を管理者が確認します。

複数ポートを安全に一覧確認する

管理対象サービスの既知ポートを少数確認する場合は、配列を使って結果をオブジェクト化できます。無関係なアドレス範囲を大量走査すると監視や侵入検知へ影響し、組織の規程に反する場合があります。自分が管理を許可された接続先と必要なポートだけに限定します。

$server = 'web01.example.com'
$ports = 80, 443
$ports | ForEach-Object {
    $test = Test-NetConnection -ComputerName $server -Port $_ -WarningAction SilentlyContinue
    [pscustomobject]@{
        ComputerName     = $test.ComputerName
        RemoteAddress    = $test.RemoteAddress
        RemotePort       = $test.RemotePort
        SourceAddress    = $test.SourceAddress
        TcpTestSucceeded = $test.TcpTestSucceeded
        CheckedAt        = Get-Date
    }
}

結果をチケットへ貼る前に、内部サーバー名、IPアドレス、利用者名などの機密性を確認します。定期監視にする場合は、認証情報をスクリプトへ平文で埋め込まず、実行頻度、タイムアウト、ログ保存期間、アラート条件を運用設計します。単発診断と監視システムは目的が異なります。

よくある誤判定

結果誤った判断正しい次の確認
ローカルでListen外部から必ず接続できる別PCからTest-NetConnection、ファイアウォール、経路
TcpTestSucceeded=Trueアプリが正常TLS、HTTP、認証、アプリログ
TcpTestSucceeded=False必ずファイアウォールDNS、経路、サーバー、待受、ACL
何も返らないポート番号は永久に空き実行時刻、権限、サービス起動後に再確認
UDPエンドポイントありネットワーク越しに応答するプロトコル固有テストとサーバーログ

「ポートが開いている」という表現は曖昧なので、報告では「サーバー上でTCP 443が0.0.0.0にListenし、PID 1234が所有」「クライアントAからweb01の192.0.2.20:443へのTcpTestSucceededはTrue」のように観測事実を書きます。これにより、アプリ担当、ネットワーク担当、サーバー担当が同じ結果を再現できます。

権限不足とアクセス拒否への対処

一部の接続情報やプロセス情報は、通常利用者では十分に取得できない場合があります。まず通常のPowerShellで試し、アクセス拒否や不足が明確な場合だけ、組織の手順に従って管理者としてPowerShellを開きます。管理者権限を得るため実行ポリシーやUACを無効にする必要はありません。会社の端末で管理者権限が提供されない場合は、実行したコマンド、時刻、エラー全文を管理者へ渡します。

期待しない待受を見つけても、Stop-Process、サービス停止、ポート予約削除、ファイアウォール無効化をその場で実行しません。変更すると通信中の利用者、監視、バックアップ、認証基盤へ影響する可能性があります。プロセスの製品名、署名、サービス、設定ファイル、変更管理者を確認し、停止が必要なら影響、作業時間、復旧方法を決めます。

確認結果を再現可能に残す

  • 実行元PC名、接続ネットワーク、VPNの有無、実行時刻
  • 接続先の正式名、解決されたIP、TCPまたはUDP、ポート番号
  • ローカルのState、LocalAddress、OwningProcess
  • リモートのSourceAddress、RemoteAddress、TcpTestSucceeded
  • 同時刻のサービス状態、イベントログ、アプリ固有テスト
  • 変更をしていないこと、または承認済み変更の内容と戻し方

一度だけ成功または失敗した結果では、瞬断や負荷分散を見落とします。必要に応じて数分間隔で少数回再確認し、結果が変わるかを見ます。短時間に大量の接続テストを送るのではなく、監視担当と頻度を調整してください。ポート確認は原因特定の一段階であり、最後は対象アプリが公式クライアントで正しく応答することまで確認します。

公式情報・参考資料

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次