前回、netstatがPowerShellではオブジェクトとして取得できることを紹介しました。
この記事では単純にGroup-Objectで状態をグルーピングしましたが、今回はログ監視として横に並べたい時の出力を考えてみましょう。
guitarrapc/PowerShellUtil - Get-NetTCPConnectionCheck | GitHub
欲しい形式はどのような感じ?
前回の記事ではGroup-Objectで縦に並べました。
PS> Get-NetTCPConnection | group state -NoElement Count Name ----- ---- 83 Established 29 Listen 8 TimeWait 6 CloseWait
さくっと確認するにはいいですが、ログで後から見直すには不便です。欲しいのはこのような形式です。
date Established Listen TimeWait CloseWait ---- ----------- ------ -------- --------- 2013/09/03 08:56:03:40 57 31 26 6
サンプル1
Object[]をPSCustomObjectに作り変える必要があります。
まず、1つ目のサンプルがこういった感じでしょうか。
function Get-NetTCPConnectionCheck{ [CmdletBinding()] param() begin { $result = [ordered]@{} } process { $result.date = (Get-Date).ToString("yyyy/MM/dd HH:mm:dd:ss") $connection = Get-NetTCPConnection $status = ($connection | group state -NoElement).Name foreach ($c in $($connection | group State -NoElement)) { $status | %{ $s = $_ if (($c | where Name -eq $s).Name -ne $null) { $result.Add("$(($c | where Name -eq $s).Name)", ($c | where Name -eq $s).count) } } } } end { return [PSCustomObject]$result } }
実行してみます。
while (1) { Get-NetTCPConnectionCheck sleep 1 }
出力結果です。
date : 2013/09/04 03:46:04:27 Established : 54 Listen : 31 CloseWait : 4 TimeWait : 1 FinWait2 : 1 date : 2013/09/04 03:46:04:28 Established : 54 Listen : 31 TimeWait : 1 CloseWait : 2 FinWait2 : 1 date : 2013/09/04 03:46:04:30 Established : 54 Listen : 31 TimeWait : 1 CloseWait : 2 FinWait2 : 1
Format-List表示になってしまいました... Format-Tableを付けても -HideTableHeadersを付けてもだめです。しかも、取得結果のPropertyを動的に取得しているが故に、ログ出力した時に状況によってはプロパティの順序が変わったりします。 ホスト画面で使っている分にはまぁいいのですが。
date Established Listen TimeWait CloseWait FinWait2 ---- ----------- ------ -------- --------- -------- 2013/09/04 03:44:04:51 60 31 5 2 1 date Established Listen TimeWait CloseWait FinWait2 ---- ----------- ------ -------- --------- -------- 2013/09/04 03:44:04:52 60 31 2 2 1 date Established Listen TimeWait CloseWait FinWait2 ---- ----------- ------ -------- --------- -------- 2013/09/04 03:44:04:53 60 31 2 2 1
サンプル2
ログでずれるのは困ります。しょうがないので、欲しいステータスだけ指定してみしましょう。 TCP Stateを全て指定してもいいですが、とりあえず良くあるので。
function Get-NetTCPConnectionCheck{ [CmdletBinding()] param() begin { $result = @{} } process { $result.date = (Get-Date).ToString("yyyy/MM/dd HH:mm:dd:ss") $connection = Get-NetTCPConnection $statuslist = @("Listen","Established","TimeWait","CloseWait","LastAck") $status = ($connection | group state -NoElement | where Name -in $statuslist).Name foreach ($c in $($connection | group State -NoElement)) { $status | %{ $s = $_ if (($c | where Name -eq $s).Name -ne $null) { $result.Add("$(($c | where Name -eq $s).Name)", ($c | where Name -eq $s).count) } } } } end { return [PSCustomObject]$result } }
実行してみます。
"Date, Listen, Established, TimeWait, CloseWait, LastAck" | Out-File -Encoding utf8 -FilePath c:\logs\tcpconnection.log while (1) { $result = Get-NetTCPConnectionCheck "$($result.date), $($result.Established), $($result.CloseWait), $($result.Listen)" | Out-File -Encoding utf8 -FilePath c:\logs\tcpconnection.log -Append sleep 1 }
結果は、当然ずれずに取得できます。
date Established Listen CloseWait ---- ----------- ------ --------- 2013/09/03 08:59:03:07 44 31 42 2013/09/03 08:59:03:08 44 31 42 2013/09/03 08:59:03:09 44 31 42 2013/09/03 08:59:03:10 44 31 42 2013/09/03 08:59:03:11 44 31 42 2013/09/03 08:59:03:12 44 31 42
実際、裏では知らせてログ取得するならこれで十分です。
取り込んだログは半角スペースをdelimiterとしてImport-CSVで取り込みも可能なので分析も容易でしょう。
あとはテキトーにちょちょいと触れば自在ですね。 netstatより簡単で気楽に作れていいものです。
追記
Sep/4/2013牟田口せんせーが解決エントリを下さいました。素敵。
PowerShell Scripting Weblog TCP/IP接続監視
これを受けて今はこうしています。
function Get-NetTCPConnectionCheck{ [CmdletBinding()] param() begin { $result = [ordered]@{} } process { $result.date = (Get-Date).ToString("yyyy/MM/dd HH:mm:dd:ss") @("Listen","Established","TimeWait","CloseWait","LastAck","FinWait2") | %{$result.$_ = 0} Get-NetTCPConnection | group state -NoElement | where name -in $result.Keys | %{$result.$($_.name) = $_.count} } end { return [PSCustomObject]$result } }
実行します。Format-Tableに-Autosizeは使えません。Autosizeするには結果を全部得ておく必要がありますが、これでは結果が得られないからです。
PS> &{ while($true) { Get-NetTCPConnectionCheck | %{ $_ | Export-Csv -Path D:\hoge.csv -NoClobber -NoTypeInformation -Append -Encoding UTF8 $_} sleep -Seconds 1 } } | Format-Table date Listen Established TimeWait CloseWait LastAck FinWait2 ---- ------ ----------- -------- --------- ------- -------- 2013/09/04 07:01:04:37 31 49 3 4 0 1 2013/09/04 07:01:04:38 31 49 3 4 0 1 2013/09/04 07:01:04:39 31 50 3 4 0 1 2013/09/04 07:01:04:41 31 49 3 4 0 1 2013/09/04 07:01:04:42 31 49 3 4 0 1 2013/09/04 07:01:04:43 31 49 3 4 0 1 2013/09/04 07:01:04:44 31 49 3 4 0 1 2013/09/04 07:01:04:45 31 49 3 4 0 1 2013/09/04 07:01:04:46 31 49 3 4 0 1 2013/09/04 07:01:04:47 31 50 3 3 0 1 2013/09/04 07:01:04:48 31 50 3 3 0 1 2013/09/04 07:01:04:49 31 50 3 3 0 1 2013/09/04 07:01:04:50 31 50 3 3 0 1
ちなみにこれはダメです。
PS> &{ while($true) { Get-NetTCPConnectionCheck sleep -Seconds 1 } } | ConvertTo-Csv -NoTypeInformation | Tee-Object d:\hoge.csv -Append | Format-Table "date","Listen","Established","TimeWait","CloseWait","LastAck","FinWait2" "2013/09/04 07:06:04:47","31","62","20","3","0","1" "2013/09/04 07:06:04:49","31","62","20","3","0","1"
大枠は出来たので、ポート指定とかはparameter / switch指定で自在に出来るでしょう。 脱netstatここになりました。 ちなみにSumoLogicで取り込むとかするならConvertTo-Json | Out-Fileでいいでしょう。