1. はじめに
現場で「どこにあるファイル?」や「この文字列がどのファイルにある?」を素早く調査するときに使う基本コマンドが Get-ChildItem(GCI)と Select-String(SS)です。本メモはIT初心者が最初の一歩で安全に使えるよう、具体例とよくある失敗、運用上の注意を書いています。
2. 基本:Get-ChildItem(ファイル・フォルダの列挙)
主な使い方(読み取り専用):
- ファイル一覧(カレントディレクトリ):
Get-ChildItem - 特定拡張子だけ:
Get-ChildItem -Filter *.log - 再帰検索(サブフォルダも):
Get-ChildItem -Recurse - ファイルのみ/ディレクトリのみ:
Get-ChildItem -File Get-ChildItem -Directory - 隠しファイル・システムファイルを含める:
Get-ChildItem -Force
よく使うオプションの意味
-Path/-LiteralPath:検索パス。-Pathはワイルドカード解釈あり、-LiteralPathは文字列をそのまま扱う-Filter:ファイル名フィルタ。ファイルシステム側で処理されるので高速(可能な限り使う)-Include/-Exclude:複数パターン指定(-Recurseと組み合わせる時の動作に注意)-Recurse:サブディレクトリを下る(PowerShell 7 以降は-Depthで深さ制限可能)-File/-Directory:結果をファイルまたはフォルダに限定-ErrorAction SilentlyContinue:アクセス拒否などのエラーを無視(ただし運用ではログを残す設計に寄せる)
実例(現場で役立つ)
- カレント以下の
.logを再帰で探してファイル名だけ表示:Get-ChildItem -Path . -Filter *.log -Recurse -File | Select-Object FullName - 30日より古いファイルだけ列挙:
Get-ChildItem -Path C:\Logs -Recurse -File | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-30) } - ネットワーク共有(パスにスペースがあれば引用):
Get-ChildItem -Path "\\server\share\path with space" -Recurse -File
パフォーマンスのコツ
-Filterを使うと高速。Where-Objectで後から絞ると遅くなることが多い。- 大量ファイルのディレクトリで
-Recurseは重い。PS7+ の-Depthや-Fileと組み合わせる。
3. 基本:Select-String(ファイルの中身を検索)
Select-String はテキストファイル内の文字列(正規表現)検索。grep に相当します。
主なオプション
-Pattern:検索パターン(正規表現)-SimpleMatch:正規表現を使わず完全/部分一致検索-CaseSensitive:大文字小文字区別-AllMatches:1行の中で複数マッチを取得-List:ファイルごとに最初のマッチだけを返す(ファイル一覧を知りたいとき便利)-Context:前後の行も表示(例:-Context 2,1)-Path:検索対象ファイルパス(ワイルドカード可)-Encoding:ファイルのエンコーディング指定(Shift_JIS など)
実例
- カレントディレクトリの全ファイルから
TODOを検索:Select-String -Pattern "TODO" -Path * - 再帰して
.csファイル内のExceptionを探す(ファイル名付き):Get-ChildItem -Path . -Filter *.cs -Recurse -File | Select-String -Pattern "Exception" - 特定フォルダ以下のファイルを再帰で検索(パイプ利用の実務型):
Get-ChildItem -Path C:\Project -Filter *.log -Recurse -File | Select-String -Pattern "ERROR" - 前後の行を確認(前2行・後1行):
Select-String -Path *.txt -Pattern "password" -Context 2,1
MatchInfo オブジェクトの利用
Select-String の結果は MatchInfo オブジェクト。主なプロパティは Path(ファイルパス)、LineNumber、Line(マッチ行)、Matches(MatchCollection)などです。
例:ファイル名と行番号だけを出す:
Select-String -Path *.log -Pattern "Exception" | Select-Object Path, LineNumber
注意点
- バイナリっぽいファイルを検索するとノイズが出る。基本はテキストファイルで使う。
- 文字コードが合わないとマッチしない。必要なら
-Encodingで明示する。
4. 実践例(組み合わせ・現場で使えるワンライナー)
- ある文字列を含むファイルの一覧(重複なし):
Get-ChildItem -Path C:\Site -Filter *.html -Recurse -File | Select-String -Pattern "KEYWORD" -List | Select-Object -ExpandProperty Path
(下書きが途中のため、以降の項目は追記予定のセクションとして枠だけ用意しています)
5. よくある失敗と対処法
- パスのワイルドカード誤爆:特殊文字を含むパスは
-LiteralPathを検討。 - -Recurse のつけ忘れ/つけ過ぎ:対象範囲を意識して、必要なら PS7+ の
-Depthを使う。 - アクセス拒否エラーで止まる:調査目的なら
-ErrorAction SilentlyContinueも選択肢。ただし「どこで拒否されたか」は別途記録したほうが安全。 - 文字コード不一致:
Select-String -Encodingを試す(Shift_JIS/UTF8 など)。
6. パフォーマンスと運用上の注意(安全運用)
- 大量ファイルへ再帰+全文検索は重い。まずは
-Filter、対象拡張子、探索深さを絞る。 - ネットワーク共有は遅くなりがち。ピーク時間の実行や広範囲検索は避ける。
- 結果を保存するなら、実行コマンドと日時もセットで残す(再現性・監査性)。
7. 破壊的操作についての強い注意(必読)
Remove-ItemやMove-Itemと組み合わせる前に、必ずSelect-Object FullName等で対象が想定通りか確認する。-Recurseと削除の組み合わせは特に危険。まずは読み取り専用で「列挙→確認→ログ保存」の手順を踏む。- 可能なら
-WhatIf(対応コマンドのみ)で事前確認し、運用では権限や承認フローも用意する。
8. PowerShell バージョン差と便利なオプション
- PowerShell 7 以降は
Get-ChildItem -Depthで再帰の深さ制限が可能。 - Windows PowerShell 5.1 と PowerShell 7 で既定の挙動(エンコーディング等)が異なるケースがある。混在環境では明示指定を増やす。
9. トラブルシューティングのヒント
- まずは対象を絞って再現:
-Filter、-File、-Depth(PS7+)。 - エラーの詳細が必要なら
-ErrorAction Stop+try/catchで捕捉してログ化。 - 検索が当たらない時は文字コード、改行コード、想定している正規表現(エスケープ)を疑う。
10. 便利ワンライナー集
- ファイルパスだけ一覧:
Get-ChildItem -Path . -Recurse -File | Select-Object -ExpandProperty FullName - 拡張子別に件数を数える:
Get-ChildItem -Path . -Recurse -File | Group-Object Extension | Sort-Object Count -Descending - マッチしたファイルだけ(ファイル単位で最初の一致のみ):
Select-String -Path .\*.log -Pattern "ERROR" -List | Select-Object Path
11. チェックリスト(箇条書き)
- まず
-Filterと拡張子で対象を絞る -Recurseは範囲を意識して使う(PS7+ は-Depthも検討)- パスに特殊文字があるなら
-LiteralPathを検討 - アクセス拒否は「無視」より「記録」できる設計に寄せる
Select-Stringは文字コード問題が出やすいので-Encodingを選択肢に- 削除・移動など破壊的操作は、列挙結果を必ず目視確認してから