🧻

PowerShellで「Write-」から始まる9種類のコマンドレットを調べた

2024/04/19に公開

概要

主に私が使用している出力系のコマンドレットは、Write-HostWrite-Output です。

それぞれの違いを雰囲気でしか把握していなかったこと。
また、Write-ではじまるコマンドレットは、他にもあり使用用途を理解していなかったこと。

この2点を解決するため、「Write-」からはじまるコマンドレットについて調べてみました。

この記事のターゲット

  • PowerShellユーザーの方
  • よく使用するWrite-Host と Write-Output の違いを理解したい方
  • 「Write-」ではじまる他の出力系コマンドレットの違いも理解したい方

環境

PowerShellのバージョン
PS C:\Users\"ユーザー名">
PS C:\Users\"ユーザー名"> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.19041.4170
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.19041.4170
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1


PS C:\Users\"ユーザー名">

PowerShellにおける出力系のコマンドレット9種類

Get-Command Write-* でWriteからはじまるコマンドレットの一覧を取得。

Writeではじまるコマンド一覧
PS C:\Users\"ユーザー名"> Get-Command Write-* -CommandType Cmdlet

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Cmdlet          Write-Debug                                        3.1.0.0    Microsoft.Pow...
Cmdlet          Write-Error                                        3.1.0.0    Microsoft.Pow...
Cmdlet          Write-EventLog                                     3.1.0.0    Microsoft.Pow...
Cmdlet          Write-Host                                         3.1.0.0    Microsoft.Pow...
Cmdlet          Write-Information                                  3.1.0.0    Microsoft.Pow...
Cmdlet          Write-Output                                       3.1.0.0    Microsoft.Pow...
Cmdlet          Write-Progress                                     3.1.0.0    Microsoft.Pow...
Cmdlet          Write-Verbose                                      3.1.0.0    Microsoft.Pow...
Cmdlet          Write-Warning                                      3.1.0.0    Microsoft.Pow...


PS C:\Users\"ユーザー名">

使用用途

各コマンドレットの使用用途を表形式でまとめました。

コマンドレット 説明 リダイレクト方法の例
Write-Output パイプラインにオブジェクトを送信。
PowerShell 2.0で導入される。
Write-Output 'Success Stream Message.' 1> Redirect01.txt
Write-Error エラーメッセージを表示。
PowerShell 2.0で導入される。
Write-Error 'Error Stream Message.' 2> Redirect02.txt
Write-Warning 警告メッセージを表示。
PowerShell 2.0で導入される。
Write-Warning 'Warning Stream Message.' 3> Redirect03.txt
Write-Verbose 詳細メッセージを表示。
PowerShell 2.0で導入される。
Write-Verbose 'Verbose Stream Message.' 4> Redirect04.txt
Write-Debug デバッグメッセージを表示。
PowerShell 2.0で導入される。
Write-Debug 'Debug Stream Message.' 5> Redirect05.txt
Write-Information 情報メッセージを表示。
PowerShell 5.0で導入される。
Write-Information 'Information Stream Message.' 6> Redirect06.txt
Write-Progress プログレスバーを表示。
PowerShell 2.0で導入される。
※ Progressストリームのリダイレクトは不可。
Write-Host コンソールにメッセージを表示。
PowerShell 5.0以降からされ、Informationストリームとして出力されるように。
5.0以降の場合:Write-Host 'Information Stream Message.' 6> Redirect06.txt
5.0より前の場合:ストリームに属さない為、リダイレクト不可。
Write-EventLog イベントログを出力 ※ ストリームに関係ないイベントビューアーに出力されるログ。

Write-Host と Write-Output の違い

違いがよくわかっていなかった Write-HostWrite-Output の違いを調べると、

  • Write-Hostは、標準出力せずにコンソールのみに表示するコマンド
  • Write-Outputは、標準出力とコンソール表示するコマンド

ということがわかりました。
コマンドレット各々の解説は後述しています。

Write-Host と Write-Information の違い

どのストリームにも属していなかった Write-Host ですが、PowerShell 5.0以降から Information ストリーム に属するようになりリダイレクトできるように。
また、同じくPowerShell 5.0から導入された、 Write-Information を使用することでも Information ストリーム に出力、かつリダイレクト可能。

それぞれのコマンドレットで Information ストリーム への出力は可能で違いが理解できなかったので、
Write-HostWrite-Information の違いを調べると、

  • Write-Hostは、コンソール表示に特化した出力コマンド
    (上記の Write-Output との違いもふまえると、標準出力せずにコンソール表示に特化した出力コマンドとなる。)
  • Write-Information は、ログを記録することに特化した出力コマンド

ということがわかりました。
コマンドレット各々の解説は後述しています。

Write-Error と Write-Warning の違い

コマンドの表記から出力するエラーレベルが変わるというのは理解できますが、具体的な動作の違いを調べると、

  • Write-Error は、続行不可能な異常が発生した場合の出力コマンド
  • Write-Warning は、続行不可まではいかないが警告すべき異常が発生した場合の出力コマンド

ということがわかりました。
コマンドレット各々の解説は後述しています。

各コマンドレットの解説・実際に実行してみる

2024年4月現在、PowerShellには出力する場所(Output Streams)が合計7種類あります。
イベントログを出力する Write-EventLog 以外のコマンドレットは、その7種類それぞれのストリームに出力するためのコマンドです。

  1. Write-Output
    Success ストリーム に出力するためのコマンドレット。一般的なIT用語にすると標準出力のこと。
     
    主にパイプラインに渡したり、変数に代入したりする目的で使用される。
     
    前述の説明では、標準出力とコンソール表示を行うと記載しているが、厳密にいうと機能は標準出力のみで、
    PowerShellウィンドウが標準出力された内容をコンソール表示しているとのこと。
     
    なお、このコマンドレットを戻り値のあるFunction内で使用した場合、期待通りの戻り値とならない。
    たとえば、Function内で Write-Output 'Test Message'と文字列(System.String)を標準出力し、戻り値を return $True と論理値(System.Boolean または bool)で指定した場合の戻り値は、論理値ではなくオブジェクト型(System.Object[])として返ってくる。
    このオブジェクトには、「標準出力した文字列」と「戻り値で設定した論理値」の2つが入ってしまう。
    Function内で Write-Output を実行する場合は、戻り値の制御で注意が必要。

    Write-Output
    PS C:\Users\"ユーザー名"> Write-Output 'Write Output Message'
    Write Output Message
    PS C:\Users\"ユーザー名">
    

    Write-Output - Microsoft Learn

  2. Write-Error
    Error ストリーム に出力するためのコマンドレット。一般的なIT用語にすると標準エラーのこと。
     
    通常、処理の続行が不可能な重大な問題が発生したケースで使用。
     
    なお、このコマンドレットを実行すると、PowerShellの自動変数 $Error に自動で格納される。
    最新のエラーは、一番要素が低い $Error[0] に格納される。要素数があがるにつれて過去のエラーを確認可能。

    Write-Error
    # エラー出力
    PS C:\Users\"ユーザー名"> Write-Error "Write Error Message" -ErrorId Err001 -Category InvalidResult
    Write-Error "Write Error Message" -ErrorId Err001 -Category InvalidResult : Write Error Message
    + CategoryInfo          : InvalidResult: (:) [Write-Error]、WriteErrorException
    + FullyQualifiedErrorId : Err001
    # エラーの履歴がある自動変数「$Error」のPropertyを確認
    PS C:\Users\"ユーザー名"> $Error[0] | Get-Member -MemberType Property
    
    
       TypeName: System.Management.Automation.ErrorRecord
    
    Name                  MemberType Definition
    ----                  ---------- ----------
    CategoryInfo          Property   System.Management.Automation.ErrorCategoryInfo CategoryInfo {get;}
    ErrorDetails          Property   System.Management.Automation.ErrorDetails ErrorDetails {get;set;}
    Exception             Property   System.Exception Exception {get;}
    FullyQualifiedErrorId Property   string FullyQualifiedErrorId {get;}
    InvocationInfo        Property   System.Management.Automation.InvocationInfo InvocationInfo {get;}
    PipelineIterationInfo Property   System.Collections.ObjectModel.ReadOnlyCollection[int] PipelineIterationInfo {get;}
    ScriptStackTrace      Property   string ScriptStackTrace {get;}
    TargetObject          Property   System.Object TargetObject {get;}
    
    
    # エラー情報を確認
    PS C:\Users\"ユーザー名"> $Error[0].Exception
    Write Error Message
    
    # エラーのIDを確認
    PS C:\Users\"ユーザー名"> $Error[0].FullyQualifiedErrorId
    Err001
    
    # エラーのCategoryを確認
    PS C:\Users\"ユーザー名"> $Error[0].CategoryInfo
    
    Category   : InvalidResult
    Activity   : Write-Error
    Reason     : WriteErrorException
    TargetName :
    TargetType :
    
    
    PS C:\Users\"ユーザー名">
    

    Write-Error - Microsoft Learn

  3. Write-Warning
    Warning ストリーム に出力するためのコマンドレット。
     
    通常、処理を続行可能だが警告が必要な問題が発生したケースで使用。

    Write-Warning
    PS C:\Users\"ユーザー名"> Write-Warning 'Write Warning Message'
    警告: Write Warning Message
    PS C:\Users\"ユーザー名">
    

    Write-Warning - Microsoft Learn

  4. Write-Verbose
    Verbose ストリーム に出力するためのコマンドレット。
     
    通常、より詳細な情報を提供したいケースで使用。
     
    デフォルトの設定だとコンソール上に表示されないが、$VerbosePreference を「Continue」にすると、
    コンソール上に出力される。
     
    また、コマンドレットにパラメーター -Verbose を指定する方法でもVerboseストリームに出力が可能。
    このパラメーターは $VerbosePreference の設定にかかわらず出力可能となる。

    Write-Verbose
    PS C:\Users\"ユーザー名"> $VerbosePreference
    SilentlyContinue
    PS C:\Users\"ユーザー名">
    PS C:\Users\"ユーザー名"> Write-Verbose 'Write Verbose Message'
    PS C:\Users\"ユーザー名">
    PS C:\Users\"ユーザー名"> $VerbosePreference = "Continue"
    PS C:\Users\"ユーザー名">
    PS C:\Users\"ユーザー名"> Write-Verbose 'Write Verbose Message'
    詳細: Write Verbose Message
    PS C:\Users\"ユーザー名">
    PS C:\Users\"ユーザー名">
    

    Write-Verbose - Microsoft Learn

  5. Write-Debug
    Debug ストリーム に出力するためのコマンドレット。
     
    通常、開発時のデバッグ出力するケースで使用。
     
    デフォルトの設定だとコンソール上に表示されないが、$DebugPreference を「Continue」にすると、
    コンソール上に出力される。
     
    また、コマンドレットにパラメーター -Debug を指定する方法でもDebugストリームに出力が可能。
    このパラメーターは $DebugPreference の設定にかかわらず出力可能となる。

    Write-Debug
    PS C:\Users\"ユーザー名"> $DebugPreference
    SilentlyContinue
    PS C:\Users\"ユーザー名">
    PS C:\Users\"ユーザー名"> Write-Debug 'Write Debug Message'
    PS C:\Users\"ユーザー名">
    PS C:\Users\"ユーザー名"> $DebugPreference = 'Continue'
    PS C:\Users\"ユーザー名">
    PS C:\Users\"ユーザー名"> Write-Debug 'Write Debug Message'
    DEBUG: Write Debug Message
    PS C:\Users\"ユーザー名">
    

    Write-Debug - Microsoft Learn

  6. Write-Information
    Informationストリーム に出力するためのコマンドレット。
     
    通常、ログファイルなどに記録するケースで使用。

    デフォルトの設定だとコンソール上に表示されないが、$InformationPreference を「Continue」にすると、
    コンソール上に出力される。
     
    また、コマンドレットにパラメーター -InformationAction を指定する方法でもInformationストリームに出力が可能。
    このパラメーターは $InformationPreference の設定にかかわらず出力可能となる。
     
    なお、Write-Host との違いは、文字色・背景色など見た目を変更できるのがWrite-Host。Informationストリーム上でタグ付けできるなどの記録ができるのがWrite-Information

    # デフォルトで実行
    PS C:\Users\"ユーザー名"> $InformationPreference
    SilentlyContinue
    PS C:\Users\"ユーザー名">
    PS C:\Users\"ユーザー名"> Write-Information "Write Information Message"
    PS C:\Users\"ユーザー名">
    # $InformationPreference を変更して実行
    PS C:\Users\"ユーザー名"> $InformationPreference = "Continue"
    PS C:\Users\"ユーザー名">
    PS C:\Users\"ユーザー名"> $InformationPreference
    Continue
    PS C:\Users\"ユーザー名">
    PS C:\Users\"ユーザー名"> Write-Information "Write Information Message"
    Write Information Message
    PS C:\Users\"ユーザー名">
    

    Write-Information - Microsoft Learn

  7. Write-Progress
    どのストリームにも出力できない。進捗バーを表示するためのコマンドレット。

    Write-Progress
    for ($i = 1; $i -le 100; $i++ ) {
        Write-Progress -Activity "Search in Progress" -Status "$i% Complete:" -PercentComplete $i
        Start-Sleep -Milliseconds 250
    }
    

    実際にWrite-Progressコマンドレットを実行した結果
    画像:実際にWrite-Progressコマンドレットを実行した結果

    Write-Progress - Microsoft Learn

  8. Write-Host
    前述している通り、コンソール出力するためのコマンドレット。

    PowerShell 5.0以降では Information ストリーム に出力されるように。
    5.0より前のバージョンでは、どのストリームにも出力できなかったため、パイプラインで送ることができなかった。
     
    このコマンドレットは、メッセージの文字色などの見た目が変更できる。ユーザーインターフェイスに重点を置いたコマンドレット。
     
    なお、Write-Host との違いは、文字色・背景色など見た目を変更できるのがWrite-Host。Informationストリーム上でタグ付けできるなどの記録ができるのがWrite-Information

    Write-Host 'This Message. Back Ground Color = "Cyan", Fore Ground Color = "Black"' -BackGroundColor Cyan -ForeGroundColor Black
    

    実際にWrite-Hostコマンドレットを実行した結果
    画像:実際にWrite-Hostコマンドレットを実行した結果

    Write-Host - Microsoft Learn

  9. Write-EventLog
    このコマンドレットは、ストリームは関係なくイベントビューアーにログを出力可能。
     
    Write-EvnetLogコマンドレットは、PowerShell 5.1まで実行可能だが、6.0以降のCoreエディションでは、実行できなくなった。
    かわりに6.0以降のCoreエディションでは、New-WinEvnetというコマンドレットで対応可能に。

    • PowerShell 5.1以前

      PowerShell 5.1までは動作する
      PS C:\Users\"ユーザー名"> Write-EventLog -LogName "Application" -Source "Windows Error Reporting" -EventID 1001 -EntryType Information -Message "Write Eventlog Message." -Category 1000
      PS C:\Users\"ユーザー名">
      

      Write-EventLog実行後にイベントビューアーを確認
      画像:Write-EventLog実行後にイベントビューアーを確認

      Write-EventLog - Microsoft Learn

    • PowerShell 6.0以降

      6.0以降では Write-EventLog が使用できない為、エラーとなる。

      6.0以降でWrite-EventLogはNG
      PS C:\Users\"ユーザー名"> Write-EventLog -LogName "Application" -Source "Windows Error Reporting" -EventID 1001 -EntryType Information -Message "Write Eventlog Message." -Category 1000
      Write-EventLog: The term 'Write-EventLog' is not recognized as a name of a cmdlet, function, script file, or executable program.
      Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
      PS C:\Users\"ユーザー名">
      

      6.0以降で新しく New-WinEvent でイベントログへの出力が可能に。

      6.0以降でNew-WinEvnetはOK
      PS C:\Users\"ユーザー名"> New-WinEvent -ProviderName Microsoft-Windows-PowerShell -Id 4100 -Payload @("PowerShell Cmdlet", "New-WinEvent", "Test Message")
      PS C:\Users\"ユーザー名">
      

      New-WinEvent実行でイベントビューアーに登録された事を確認
      画像:New-WinEvent実行でイベントビューアーに登録された事を確認

      New-WinEvent - Microsoft Learn

    補足情報:PowerShellでイベントログを出力する方法をより深く調べました < クリックで折りたたみが開く >

    既存のイベントソース(イベントプロバイダー)やイベントIDを調べる方法や、自作のイベントソースを作る方法も調べました。
     
    また、6.0以降の環境下において自作のイベントソースで出力したい場合、New-WinEventでは対応できなかった為、違う方法で検証しています。
     
    詳しくは、下記の記事をご参照ください。

参考情報

https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_output_streams
https://blog.shibata.tech/entry/2015/06/26/001944

まとめ

PowerShellの出力系のコマンドの違いをおさえることができた!

違いは下記のとおり。

  • Write-Output:パイプラインにオブジェクトを送信
  • Write-Error:エラーメッセージを表示
  • Write-Warning:警告メッセージを表示
  • Write-Verbose:詳細メッセージを表示
  • Write-Debug:デバッグメッセージを表示
  • Write-Information:情報メッセージを表示
  • Write-Progress:プログレスバーを表示
  • Write-Host:コンソールにメッセージを表示
  • Write-EventLog:イベントログを出力(PowerShell 5.1以前で動作)
    6.0以降のCoreエディションでは、New-WinEvnetで対応。

関連記事

https://zenn.dev/haretokidoki/articles/0a179fe71a2cc8
https://zenn.dev/haretokidoki/articles/af3e404855c54b
https://zenn.dev/haretokidoki/articles/48de2dc693f9c0
https://haretokidoki-blog.com/pasocon_powershell-startup/
https://zenn.dev/haretokidoki/articles/7e6924ff0cc960

GitHubで編集を提案

Discussion