💪

PowerShellの出力を理解する

に公開

はじめに

Unix系のコマンドでは、標準出力とエラー出力の二種類の出力があります。PowerShellでは、更に多くの種類の出力があります。具体的な内容は以下のヘルプに記載されています。

https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_output_streams?view=powershell-7.4

主なものを抜き出すと以下のようになります。

ストリーム 説明 導入バージョン 書き込みコマンドレット
1 成功ストリーム PowerShell 2.0 Write-Output
2 エラー ストリーム PowerShell 2.0 Write-Error
3 警告ストリーム PowerShell 3.0 Write-Warning
4 詳細ストリーム PowerShell 3.0 Write-Verbose
5 デバッグ ストリーム PowerShell 3.0 Write-Debug
6 情報ストリーム PowerShell 5.0 Write-Information
該当なし Progress (日本語名不明) PowerShell 5.0 Write-Progress

ここでいうストリームとは出力されるデータになります。ストリームの種類は、データの種類くらいに考えておくと整理がつきやすいと思います。

成功ストリームについて

コマンドレットを実行した際に出力されるデータです。Write-Outputでストリームを明示的に指定できます。公式のヘルプはこちらになります。

https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.utility/write-output?view=powershell-7.4

コマンドレットを実行したときに正常終了した際にデータが出力されるストリームです。Write-OutPutを使用しなくても、このストリームでデータが出力されます。なので、明示的に成功ストリームを指定したいケースでもなければ、Write-Outputを使用しなくても大丈夫です。

エラーストリームについて

コマンドレットを実行してエラーが起きた時に出力されるデータです。関数やスクリプトでエラーが起きた時に出力したいときは、Write-Error のコマンドレットで出力することができます。公式ヘルプはこちらになります。

https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.utility/write-error?view=powershell-7.4

こちらのコマンドレットを実行すると実際にエラーになります。関数やスクリプトで、エラーの判定を出してtry catch でエラー処理を行わせたい場合にも利用します。

> Write-Error "Error_1"
Write-Error: Error_1
# Write-Error を実行すると、エラーが出力されます。

> Write-Error "Error_2"
Write-Error: Error_2
> Write-Error "Error_3"
Write-Error: Error_3
# エラーを何度か出力します。

PS C:\Users\Main> $Error
Write-Error: Error_3
Write-Error: Error_2
Write-Error: Error_1
# $Errorにエラー出力が記録されます。

また、Write-Errorにはエラーの種類に関する細かい設定をするためのオプションが実装されています。これらのオプションを利用することで、きめ細かく出力するエラーの設定を行うことができます。

PS C:\Users\Main> Write-Error -Exception
Exception            TargetObject         CategoryTargetType   InformationAction    OutVariable
Message              RecommendedAction    Verbose              ProgressAction       OutBuffer
ErrorRecord          CategoryActivity     Debug                ErrorVariable        PipelineVariable
Category             CategoryReason       ErrorAction          WarningVariable
ErrorId              CategoryTargetName   WarningAction        InformationVariable

警告ストリームについて

Write-Warning のコマンドレットで出力することができます。公式ヘルプはこちらになります。

https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.utility/write-warning?view=powershell-7.4

コマンドレットの使い方は、出力する内容を以下のように指定するだけです。

> Write-Warning "Warning"
WARNING: Warning

エラーストリームと警告ストリームの違いは重要度になります。また、Write-Warning を実行してもWriteーError のようにエラーとしては扱われません。

詳細ストリームについて

Write-Verbose で出力される出力です。公式のヘルプはこちらになります。

https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.utility/write-verbose?view=powershell-7.4

コマンドレットで -Verbose のオプションをつけると表示されます。

> Write-Verbose "Verbose"
# 普段は何も表示されない。

> Write-Verbose "Verbose" -Verbose
VERBOSE: Verbose
# -Verbose のオプションをつけると表示される。

常に表示したい場合は、$VerbosePreference の変数に Continue を指定します。

> $VerbosePreference = 'Continue'
> Write-Verbose "Verbose"
VERBOSE: Verbose
# 変数で環境の設定を行うことで、-Verbose のオプションをつけなくても詳細ストリームの情報が表示される。

情報ストリームについて

Write-HostやWrite-Informationをで出力されます。プロンプトには成功ストリームのように表示されます。ただし、詳細ストリームで出力した内容は、リダイレクトした時にファイルに出力されません。関数を作成したときに、出力を拾われたくないときなどに利用できます。

> Write-Information -MessageData "Test" > pou.txt
> Get-Content .\pou.txt

なぜこれだけ出力の種類があるのか

シェルスクリプトであれば、出力されるデータは文字列です。PoewrShellのコマンドレットを実行して出力されるのはオブジェクトです。

「画面にはいろいろ表示させたいけど、出力されるのはオブジェクトだけにしたい。」

このようなニーズがあったとき、ストリームの種類をうまく区別することで実現できます。また、インタラクティブに動かせるようなツールも、ストリームをうまく使いこなすことで実現しやすくなります。

ストリームを区別して出力するようなコマンドレットを単体で利用する用途はあまりないと思います。しかし、スクリプトや関数を書く際にストリームを意識しておくと、洗練したものがかけるのではないでしょうか。

Discussion