PowerShell リダイレクト演算子のネイティブコマンドへの適用方法


PowerShell リダイレクト演算子

PowerShellリダイレクト演算子には以下がある。

演算子 説明 シンタックス
> 指定したストリームをファイルに送信 n>
>> 指定したストリームをファイルに追加 n>>
>&1 指定したストリームを成功ストリームにリダイレクト n>&1

n はストリーム番号を表し、指定しない場合はデフォルトの 1 が指定されたものとして扱われる。


ストリーム番号は以下が定義されている。

ストリーム番号 説明 導入バージョン Write Cmdlet
1 Success Stream PowerShell 2.0 Write-Output
2 Error Stream PowerShell 2.0 Write-Error
3 Warning Stream PowerShell 3.0 Write-Warning
4 Verbose Stream PowerShell 3.0 Write-Verbose
5 Debug Stream PowerShell 3.0 Write-Debug
6 Information Stream PowerShell 5.0 Write-InformationWrite-Host
* All Streams PowerShell 3.0


リダイレクト操作

PowerShell スクリプトから外部ネイティブ コマンドを実行する場合は、標準出力(stdout)と標準エラー出力(stderr)だけ気にすれば良い。

ネイティブ コマンドを実行して、その標準出力をファイルに出力する場合は以下のようになる。

.\foo.exe > bar.log

この場合、標準出力はファイルに、標準エラー出力はコンソールに表示される。標準エラー出力のみをファイルに出力する場合は以下のようになる(標準出力はコンソールに表示される)。

.\foo.exe 2> bar.log


標準出力と標準エラー出力を、共にファイルに出力したい場合は以下のようにできる。

.\foo.exe *> bar.log

または、全てのストリームを成功ストリーム(Success Stream)にリダイレクトしたものをファイル出力しても同様。

.\foo.exe *>&1 > bar.log


標準エラー出力とPowerShell Error Stream

Error ストリームは、error結果の既定のストリームです。 Write-Error コマンドレットを使用して、このストリームに明示的に書き込みます。 Error ストリームは、ネイティブ アプリケーションの stderr ストリームに接続されます。 ほとんどの条件下では、これらのエラーによって実行パイプラインが終了する可能性があります。 このストリームに書き込まれたエラーは、 $Error 自動変数にも追加されます。

前述のようにリダイレクト演算子にてネイティブ コマンドの標準出力(stdout)と標準エラー出力(stderr)をファイル書き出しができるが、ネイティブ コマンドの標準エラー出力は、PowerShell のエラーストリームとしてラップされ、そのエラーは以下のように報告される(余計なエラー出力がファイルに追加される)。

.\foo.exe : xxx
発生場所 xxx.ps1:1 文字:1
+ .\foo.exe *>&1 > bar.log
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (xxx) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

通常、ネイティブ コマンドは標準エラー出力を詳細情報の表示に積極的に使うため、上記エラー出力が頻発することになる。


以下のようにパイプライン内のオブジェクトを Foreach-Object で文字列展開すれば、ネイティブ コマンドの標準エラー出力をそのままファイル書き込みすることができる。

.\foo.exe *>&1 | %{ "$_" } | Out-File bar.log

追記したりエンコード指定したりする場合は以下。

.\foo.exe *>&1 | %{ "$_" } | Out-File bar.log -Append -Encoding utf8