ポートをリッスンしているのは誰なのか (Windows)

こんにちは、エス・ワイ・シーの松本です。

Windows 環境のセットアップとかしていて、複数のソフトを1つの
環境に同居させる必要がある場合などに、ごくたまに遭遇するケース。
「ポート 80 は既に使用済みです。」

多くの場合この手の必要通信ポートが既に使用済みとして
エラーになる場合、セットアップ実施している側はこれまでに入れたソフトウェアとかで
暗黙的に使用されていたりして、何が使っているか簡単にわからなくて
面倒だったりするんですよね。

特に既存で運用中の環境であったりとか、別の人が作業した後とか。

そんな時どうするかと言いますと、コマンドプロンプトなどで

~~~
netstat -an

アクティブな接続

プロトコル ローカル アドレス 外部アドレス 状態
TCP 0.0.0.0:135 0.0.0.0:0 LISTENING
TCP 0.0.0.0:445 0.0.0.0:0 LISTENING
~~~


とかすると バインドされているポート番号なんかは列挙されて「使用されていること」は分かるのだけれど
結局誰が使っているのかはわからない。
そこで “b” オプションも追加して実態を探ろうとするわけですが、

~~~
netstat -anb

要求された操作には管理者特権が必要です。

~~~
作業者が管理権限を教えてもらっていないなどの場合に操作できない場合があります。

管理者権限があり、管理者モードで開いたコマンドプロンプトで実行しても

~~~
netstat -anb

アクティブな接続

プロトコル ローカル アドレス 外部アドレス 状態
TCP 0.0.0.0:135 0.0.0.0:0 LISTENING
RpcSs
[svchost.exe]
TCP 0.0.0.0:445 0.0.0.0:0 LISTENING
所有者情報を取得できません
~~~

ポート 135 については「RpcSs」という名前と「svchost.exe」という実態であることは分かった。
ポート 445 については「分からない」ということが分かった。


仕方ないのでプロセス情報から追いかけてみるとする。”o” オプションを指定する。
~~~
netstat -ano

アクティブな接続

プロトコル ローカル アドレス 外部アドレス 状態 PID
TCP 0.0.0.0:135 0.0.0.0:0 LISTENING 1260
TCP 0.0.0.0:445 0.0.0.0:0 LISTENING 4
~~~
これは管理者権限なくとも表示できる。

続いて、プロセス ID が何者であるかを確認する。

~~~
tasklist /fi “PID eq 1260” /v /fo list

イメージ名: svchost.exe
PID: 1260
セッション名: Services
セッション#: 0
メモリ使用量: 16,728 K
状態: Unknown
ユーザー名: N/A
CPU 時間: 0:00:20
ウィンドウ タイトル: N/A


tasklist /fi “PID eq 1260” /svc /fo /list

イメージ名: svchost.exe
PID: 1260
サービス: RpcEptMapper
RpcSs

~~~
なるほど、ポート 135 については 「svchost.exe」が実体で、サービスのものであり
「RpcEptMapper」「RpcSs」というのは分かった。


~~~

tasklist /fi “PID eq 4” /v /fo list

イメージ名: System
PID: 4
セッション名: Services
セッション#: 0
メモリ使用量: 2,448 K
状態: Unknown
ユーザー名: N/A
CPU 時間: 0:17:38
ウィンドウ タイトル: N/A


tasklist /fi “PID eq 1260” /svc /fo /list

イメージ名: System
PID: 4
サービス: N/A

~~~

ポート 445 の実体は 「System」でサービスというのは分かった。


しかしまぁ、面倒くさいし、わかりにくい感じがしますね。


こんな時には、PowerShell を使いましょう。
以降の説明にある方法が利用可能かどうかは PowerShell 環境によります。
Windows 10 / Windows Server 2016 以降なら問題なく利用可能です。

利用できるかどうか確認方法
PowerShell を起動し、以下のコマンドを実行します。

~~~
Get-Module -ListAvailable NetTCPIP

ModuleType Version Name ExportedCommands
———- ——- —- —————-
Manifest 1.0.0.0 NetTCPIP {Get-NetIPAddress, Get-NetIPInterface, Get-NetIPv4Protocol…
~~~

NetTCPIP モジュールがあれば大丈夫です。
利用準備をします。

~~~
Import-Module NetTCPIP
~~~

以下のコマンドで確認します。
TCP ポートの場合 Get-NetTCPConnection -LocalPort ポート番号
UDP ポートの場合 Get-NetUDPEndpoint -LocalPort ポート番号
※ -LocalPort オプションを省略してポート番号指定しない場合、すべてのポート情報が列挙されます。


~~~
Get-NetTCPConnection -LocalPort 135 | fl

LocalAddress : ::
LocalPort : 135
RemoteAddress : ::
RemotePort : 0
State : Listen
AppliedSetting :
OwningProcess : 1260
CreationTime : 2020/10/29 13:15:12
OffloadState : InHost

LocalAddress : 0.0.0.0
LocalPort : 135
RemoteAddress : 0.0.0.0
RemotePort : 0
State : Listen
AppliedSetting :
OwningProcess : 1260
CreationTime : 2020/10/29 13:15:12
OffloadState : InHost
~~~
IPv6 / IPv4 両方でリッスンしていることがわかります。
プロセス ID 1260


~~~
Get-NetTCPConnection -LocalPort 445 | fl

LocalAddress : ::
LocalPort : 445
RemoteAddress : ::
RemotePort : 0
State : Listen
AppliedSetting :
OwningProcess : 4
CreationTime : 2020/10/29 13:17:34
OffloadState : InHost

~~~

ここからいろいろ確認していくと詳細な情報が確認できるのですが、、、
いちいちやっぱり面倒ですね。

こんなときどうするのか?
PowerShell ならではの便利なツールを使いましょう。
ツールを使うための準備をします。

~~~
mkdir C:\temp\tool
cd c:\temp\tool
~~~

ツールは PowerShell Gallery から入手します。
まずは PowerShell Gallery と通信できるかどうかの確認から。

~~~
Find-Module -Name SHIMSOFT-NetProcess

Version Name Repository Description
——- —- ———- ———–
1.3 SHIMSOFT-NetProcess PSGallery Get-NetTCPConnection / Get-NetUDPEndpo…

~~~

結果が表示されたら概ね大丈夫なので、ツールを手元に保存します。


~~~
Save-Module -Name SHIMSOFT-NetProcess -Path .\

dir

Mode LastWriteTime Length Name
—- ————- —— —-
d—– 2020/10/29 15:04 SHIMSOFT-NetProcess

~~~

ツールを使うための確認をします。

~~~
Get-ExecutionPolicy
RemoteSigned
~~~
もしも 「Restricted」の場合は実行できません。
管理者権限が必要となりますが、以下のコマンドで RemoteSigned に変更します。

~~~
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
~~~
これは1度実行しておくと再設定するまで状態保持するので、
必要に応じて管理者の人に一回設定してもらえれば大丈夫です。

ツールを使う
~~~
Import-Module .\SHIMSOFT-NetProcess\1.3\SHIMSOFT-NetProcess.psd1

Get-NetProcess -LocalPort 135

Type Binding Information State Name
—- ——————- —– —-
Service :: TCP: 135 Listen RPC Endpoint Mapper
Service 0.0.0.0 TCP: 135 Listen RPC Endpoint Mapper
~~~
Name の列が「RPC Endpoint Mapper」となっていますが、これはサービス管理ツール上で
表示される名前と同じものです。

nestat などでは「svchost.exe」「RpcEptMapper」「RpcSs」はわかりましたが
サービス管理ツールなどでの表示までたどり着いていませんでした。
それがこの Get-NetProcess コマンドでは分かりやすい名前まで表示されます。
・・・逆に「svchost.exe」「RpcEptMapper」「RpcSs」のいずれかが知りたい時に困るのでは??
なるほど、一理あります(?)


~~~
Get-NetProcess -LocalPort 135 | fl *

(結果一部抜粋)

State : Listen
ProcessId : 1260
Process : System.Diagnostics.Process (svchost)
ProcessName : svchost
Name : RPC Endpoint Mapper
FileVersionInfo :
FileName : C:\WINDOWS\system32\svchost.exe -k RPCSS -p
ServiceDetail : Win32_Service: RPC Endpoint Mapper (Name = “RpcEptMapper”)
ServiceName : RpcEptMapper
ServiceDisplayName : RPC Endpoint Mapper
ServicePathName : C:\WINDOWS\system32\svchost.exe -k RPCSS -p

ServiceDescription :
トランスポートのエンドポイントに対するRPC インターフェイス識別子を解決します。
このサービスが停止または無効の場合、リモート プロシージャ コール (RPC)
サービスは正常に機能しません。

Type : Service

~~~

どうでしょうか。「svchost.exe」「RpcSs」「RpcEptMapper」というキーワードも
確認できますし、何ならファイルの実体の所在地までわかりますね。
いいんじゃないでしょうか。

管理者権限で開いてない PowerShell でもある程度情報が収集できます。
管理者権限で開いていないと取れない情報もやはりあるので、万全を期すには
管理者権限で開いた PowerShell 上での実行が望ましくはあります。


作業環境にインストールしても大丈夫、という場合、

Install-Module -Name SHIMSOFT-NetProcess

とすると既定の保存先に保存され、もっと簡単に使えるようになります。
ツールを使いたい環境がインターネットに接続されていない場合、
Save-Module で保存したフォルダ内用を USB メモリなどでコピーするなどしても
利用可能です。


使い方がよくわからない場合以下のコマンドでヘルプを参照できます。

help Get-NetProcess -full