PowerShell入門③|パイプラインで必要な行だけ拾う

PowerShell入門③|パイプラインで必要な行だけ拾う PowerShell

パイプラインを知らないと、こう聞かれたときに手が止まります。「今、PC が重いんですけど、何が悪さしてるか分かります?」

こう聞かれたとき、タスクマネージャーを開いて、メモリの列をクリックして、上から眺める。これも悪くないんですが、100台分、同じことをやってと言われたら、ちょっと手が止まります。

PowerShell なら、「メモリを食っているプロセスの上位5つ」を、1行で取り出せます。これを支えているのが、今回の主役、パイプラインです。

シリーズ「情シスのための PowerShell 入門」の第3回です。前回(第2回:基本コマンド10選)で、PC の状態を見る方法を覚えました。今回は、見た結果から、必要なものだけを取り出す番です。

結論:パイプラインは「文字」ではなく「モノ」を流す

パイプライン(|)は、前のコマンドの結果を、次のコマンドに渡す仕組みです。cmd にもパイプはありますが、流れるのは文字です。PowerShell では、プロセスやサービスといったオブジェクト(モノ)が流れます。

モノは、名前や状態などの項目(プロパティ)を持っています。だから、「状態が Running のものだけ」「メモリの大きい順」といった指定が、文字の位置を数えなくてもできます。

パイプラインで使う、5つのコマンド

やりたいこと コマンド イメージ
条件に合うものだけ Where-Object 「Running のものだけ」
必要な項目だけ表示 Select-Object 「名前とメモリだけ」
並べ替え Sort-Object 「大きい順」
数える・集計する Measure-Object 「何件?合計は?」
種類ごとに分ける Group-Object 「状態ごとに何件?」

メモリを食っているプロセスの上位5つ

Get-Process | Sort-Object WorkingSet -Descending | Select-Object -First 5 Name, @{n='MB';e={[math]::Round($_.WorkingSet/1MB)}}
パイプラインの実行画面。Get-Process を Sort-Object で並べ替えて上位5件だけを取り出し、メモリ使用量を MB で表示した画面。サービスの状態ごとの件数と、動いているサービスの数も表示している

順番に読むと、こうなります。

  1. Get-Process:プロセスを取得する(モノが流れ出す)
  2. Sort-Object WorkingSet -Descending:メモリ使用量(WorkingSet)の大きい順に並べる
  3. Select-Object -First 5 Name, ...:先頭の5件だけ、名前とメモリ(MB に直したもの)を表示する

WorkingSet は、第1回で紹介した Get-Member で見つけた項目です。項目名が分からなくなったら、| Get-Member を付ければ、一覧が出ます。

サービスを数える・分ける

画面の下半分は、サービスの話です。

Get-Service | Group-Object Status
(Get-Service | Where-Object Status -eq Running).Count
  • Group-Object Status は、状態(Running / Stopped)ごとに、件数を出します。僕の PC では、止まっているサービスが178個、動いているサービスが154個でした。
  • Where-Object Status -eq Running で、動いているものだけに絞り、.Count で数えています。

-eq は「等しい」、-gt は「より大きい」、-lt は「より小さい」、-like は「パターンに合う」。比較は、= や > ではなく、この - 付きの演算子を使います。……と、軽く書きましたが、これが、次の「やらかし」の原因です。

僕のやらかし:フォルダーに「5」が増えていく

「CPU を5秒以上使っているプロセス」を探そうとして、cmd や他の言語の癖で、こう書きました。

Get-Process | Where-Object CPU > 5

画面には、何も出ません。「あれ、該当なし?」と思って、ふとフォルダーを見ると、5 という名前のファイルができていました。

パイプラインの失敗例。Where-Object CPU > 5 を実行したあとの Get-ChildItem の画面。フォルダーに 5 というファイルができている。続けて、正しく -gt を使うと、該当するプロセスの件数が出る

PowerShell では、> はリダイレクト(出力をファイルに書き出す)の記号です。つまり、「Where-Object CPU の結果を、5 というファイルに書き出す」と読まれていたんです。画面に何も出なかったのは、全部ファイルに行ったからでした。

正しくは -gt です。

Get-Process | Where-Object CPU -gt 5 | Measure-Object

僕の PC では、CPU を5秒以上使ったプロセスが117件でした。比較には -gt、-eq、-like。> と = は使わない。 食べ放題でうっかり「5」を持ち帰ってしまった気分です。

実務で使うときのコツ

  • まず Get-Member で項目を確認する。名前が分かれば、あとは並べるだけ
  • 絞り込みは、なるべく手前で。Get-Process notepad のように、最初のコマンド側で絞れるものは、そちらで絞ると速い
  • Format-Table は、最後に。整形したあとは、もう「モノ」ではなく、表示用のデータなので、絞り込みや並べ替えができなくなります
  • 数が多いときは、Select-Object -First 10 で、まず一部だけ見て、様子を確かめる

今回覚えたコマンド

コマンド 意味
パイプ(縦棒の記号) 結果を次のコマンドに渡す
Where-Object 条件で絞る(-eq / -gt / -lt / -like)
Select-Object 項目や件数を選ぶ(-First / -Last)
Sort-Object 並べ替え(-Descending で大きい順)
Measure-Object 数える・合計する
Group-Object 種類ごとに分ける

次回予告

次回は、ここまでのコマンドをスクリプト(.ps1)にして、使い回せるようにします。変数、if、foreach、そして実行ポリシー。「ダブルクリックしたらメモ帳が開いた」「文字化けして動かない」という、初心者が誰でも通る道も、一緒に潰します。

→ 第4回:スクリプト入門と実行ポリシー

参考

ITもごはんも、腹八分目が長続きのコツ!

コメント