PowerShellのGet-Contentコマンドの詳細ガイド:5つの実用的な例で理解するを安全に進める結論は「Get-Contentはfileを行またはraw文字列として読み取るcommandです。先頭・末尾・件数を限定して内容とencodingを確認し、監視は-Tailと-Wait、構造保持が必要なJSONやCSVは専用cmdletへ渡します。」です。Windows PowerShell 5.1とPowerShell 7.xで既定encodingの差を意識し、large logは全件をmemoryへ載せないという前提を外すと同じ入力でも結果が変わります。まず少量をread-onlyで取得し、型とencodingを確認してから読取範囲を広げます。
読取前にpath・size・encodingを確かめる
Get-Contentでファイルを読む前に、LiteralPath、ファイルサイズ、文字コード、改行形式を確認します。全体を一つの文字列として扱うRaw、末尾監視のTail、分割単位を変えるReadCountでは戻り値の型と件数が異なります。小さなサンプルで型を表示し、巨大ファイルを不用意にメモリーへ載せない構成を選びます。
- Get-Itemでpath、size、LastWriteTime、属性を確認する
- Get-Content -TotalCount 5で少量を読み文字化けを確認する
- Get-Help Get-Content -Parameter Encodingで利用版の候補を確認する
- 機密logをconsole、transcript、ticketへ露出しない
行配列・Raw文字列・byte列の型を分ける
既定では一行ずつ文字列objectが流れます。配列indexは0から始まるため、先頭行はindex 0です。件数を安定して調べるには、小さなfileで @(Get-Content -LiteralPath …) のように配列として受けます。-Rawは改行を含む一つの文字列、-ReadCount 0は全行をまとめた出力になるため、large fileではmemory負荷を確認します。文字列のLengthはUTF-16のコード単位数、配列のCountは要素数であり、fileのbyte数とは異なります。
TotalCount・Tail・ReadCountを用途で選ぶ
先頭だけを確認
Get-Content -LiteralPath 'C:\Logs\app.log' -TotalCount 20
LiteralPathは角括弧などをwildcardとして解釈しません。先頭20行で形式と文字化けの有無を確認します。ただし、TotalCountはbyte数の上限ではないため、改行のない巨大fileでは先頭1行でも大量のmemoryを使うことがあります。
末尾と追記を監視
Get-Content -LiteralPath 'C:\Logs\app.log' -Tail 50 -Wait
-Waitはfileの追記を待ち続けるため、終了はCtrl+Cです。log rotation後の動作を実環境で確認し、長時間sessionの監視手段とは分けます。
一つの文字列として読む
$json = Get-Content -LiteralPath '.\settings.json' -Raw -Encoding utf8
$json | ConvertFrom-Json
-Rawは行配列ではなく単一文字列を返します。JSONは文字列分割せずConvertFrom-Jsonで解析します。ただし、解析成功だけでは設定に必要なキーや値の型まで検証できません。空の入力への対処は後述の例を参照してください。
大きなfileをstream処理
Get-Content -LiteralPath '.\access.log' -ReadCount 1000 |
ForEach-Object { $_ | Select-String -SimpleMatch ' 500 ' }
この例のReadCount 1000は最大1000行ずつをpipelineへ渡し、ForEach-Objectの中で各行を検索します。byte数やmemory使用量を固定する指定ではなく、巨大な一行は分割されません。また、結果を変数へ全件保存するとその分のmemoryを使います。単純な検索ならSelect-Stringへpathを直接渡す方法もありますが、同じencodingを明示して比較します。特にWindows PowerShell 5.1ではBOMなしfileに対する両commandの既定encodingが異なります。
byteとして確認
Get-Content -LiteralPath '.\sample.bin' -AsByteStream -ReadCount 32 | Select-Object -First 1
-AsByteStreamはPowerShell 7系でbyteを読む用途です。binaryをtextとして表示せず、版のhelpでparameter有無を確認します。
PowerShell版によるencoding差を確認する
BOMがない場合、Windows PowerShell 5.1のGet-Contentは既定でシステムのANSIコードページを使い、PowerShell 7.xはUTF-8を使います。UTF-8と分かっているfileは -Encoding utf8 を明示します。読取時の指定はBOMを付けたり消したりする操作ではなく、BOMなしUTF-8も対象です。元の文字コードは作成元の仕様やbyte列と照合し、次の使い方を避けます。
- 未知のlarge fileを全件読込する
- PathとLiteralPathを混同する
- encodingを端末の見た目だけで断定する
- -Waitをservice監視の代替にする
- JSONやCSVを文字列splitで解析する
機密logをconsoleへ出し過ぎない
読取commandでも、credentialやtokenを含むlogを画面・transcriptへ出すと漏えいになります。最小行だけをtestし、共有用copyでは承認済みmask処理を使います。出力redirectを入力と同じfileへ向けず、加工は別fileに保存します。変更が必要なら元fileのhashとACLを記録してcopyを作り、検証後に採用します。不合格ならcopyを破棄し元fileを保持します。
空fileと巨大一行をsampleで再現する
まずGet-ItemのLengthでbyte数を確認します。行objectの件数は Get-Content -LiteralPath … | Measure-Object のCountで確認できますが、全体を読むため大きなfileでは時間がかかります。Measure-Object -Lineによる文字列内の行数とは区別します。-Raw、通常読取、明示encodingの差は小さなsampleで比較し、先頭・末尾・既知行も確認します。読み取りだけなら原本は変更しません。以下の一時file作成や加工出力は原本と別pathへ限定します。
Count・Length・byte数で読取結果を確定する
Get-Contentは既定で行objectを返し、-Rawは一つのstring、-AsByteStreamはbyteを返します。-Tailだけなら末尾の指定行数を読み終えると終了し、-Waitを付けると追記を待ちます。更新中fileの読取は、一時点の整合したsnapshotを保証しません。読み取り成功、fileなし、文字化け、監視中rotationを分けて判定します。
Raw JSONを読み専用parserへ渡す
$raw = Get-Content -LiteralPath '.\settings.json' -Raw -Encoding utf8 -ErrorAction Stop
if ([string]::IsNullOrWhiteSpace($raw)) {
throw 'settings.json は空、または空白のみです。'
}
$obj = ConvertFrom-Json -InputObject $raw -ErrorAction Stop
$type = if ($null -eq $obj) { '(null または出力なし)' } else { $obj.GetType().FullName }
[pscustomobject]@{ Chars = $raw.Length; Type = $type }
JSONのnullや、配列の列挙によって出力がなくなった場合に備え、GetTypeの前で $null を確認します。このTypeは代入後のPowerShellの型であり、JSONの最上位が配列かどうかの厳密な判定には使いません。PowerShell 7.xで最上位の配列を保持したい場合はConvertFrom-Jsonに -NoEnumerate を付けます。
空fileと読取失敗をLengthとErrorRecordで識別する
- 期待型で読取成功:期待する型と件数で内容を取得し、-Rawなら改行を保った一つのstringになる
- 空file:0byteのfileでは通常読取の出力は0件です。Rawの結果が $null か空stringかを区別し、文字列への変換後のLengthとfile sizeを併記します
- 読取エラーとencoding不一致:path不存在、共有違反、権限不足など、commandが報告するエラーは -ErrorAction Stop とtry/catchで扱います。ただし、誤ったencodingでも文字化けした文字列が返り、エラーにならないことがあります。ErrorActionは文字コードを検証する指定ではありません
巨大fileを-ReadCount 0や-Rawで全量memoryへ載せず、行の長さも考慮してbatch sizeを決めます。巨大一行を固定サイズで読む必要がある場合は、別途byte単位で分割して処理する設計が必要です。-Waitには時間指定のtimeout引数はないため、Ctrl+Cや呼出側の停止管理を使います。-TotalCountとの併用では指定行数に達すると終了し、file削除でも待機が中断されます。log rotationの方式に応じて再接続を確認します。
BOM・改行・更新中logを境界にする
# 既存のempty.txtを上書きせず、一意な0byteの一時fileを作成する
$tempFile = [System.IO.Path]::GetTempFileName()
try {
$lines = @(Get-Content -LiteralPath $tempFile -ErrorAction Stop)
$raw = Get-Content -LiteralPath $tempFile -Raw -ErrorAction Stop
[pscustomobject]@{
Lines = $lines.Count
RawIsNull = ($null -eq $raw)
RawLength = ([string]$raw).Length
Bytes = (Get-Item -LiteralPath $tempFile -ErrorAction Stop).Length
}
}
finally {
Remove-Item -LiteralPath $tempFile -ErrorAction Stop
}
この例は作成した一時fileだけをfinallyで削除します。Lines、RawLength、Bytesは0を期待し、RawIsNullでRawの戻り値も確認します。空、末尾改行あり/なし、CRLF、UTF-8 BOM有無、長い一行、更新中logは別々の小さなsampleでtestし、型、Count、Length、byte数、encoding、rotation時の再接続条件を記録します。
通常読取のCount、-RawのLength、Get-Itemのbyte数は同じ指標ではありません。期待する型を先に決め、empty fileや末尾改行なしでも判定が崩れないfixtureを残します。


コメント