前回のエントリの補足です。
前回はWrite-HostとWrite-Outputの違いについて触れ、全くの別物であることを説明しました。
別物であるとはいえ、実際の利用においては両方ともコンソールに文字列を表示する用途で同様に扱うことが多いと思います。
そこで本エントリではコンソールに文字列を表示する場合の両者の違いについて説明していきます。
Write-Host、Write-Outputの入力パラメータについて
本題に入る前に、Write-HostとWrite-Outputの入力パラメータについて軽く触れます。
Write-Hostの-Object、Write-Outputの-InputObjectは名前付き引数にも関わらず複数の入力を受け付けることができ可変長引数の様に振る舞います。
# Write-Hostの入力パラメータ -Object が3つの引数を受け取り可変長の様に振る舞っている PS C:\> Write-Host 123 456 789 123 456 789 # Write-Outputの -InputObject パラメーターも同様 PS C:\> Write-Output 123 456 789 123 456 789
一見不可解な動作ですが、これはWrite-Hostの-Object、Write-Outputの-InputObjectパラメータにValueFromRemainingArguments属性が設定されているためです。
ValueFromRemainingArguments属性についてはabout_Functions_Advanced_Parametersに詳細が記載されており、
ValueFromRemainingArguments 引数は、パラメーターが、関数の他のパラメーターに割り当てられていないコマンド内のすべてのパラメーター値を受け取ることを示します。
との説明がなされています。
これは、例えば3つのパラメーターを持つ関数を5つの引数で呼び出した場合2つの引数が余りますが、ValueFromRemainingArguments属性が付いているパラメーターにこの余りをまとめてリストとして渡されます。
言葉で説明するより以下の例を見た方がわかりやすいと思います。
ValueFromRemainingArguments属性が付いた-Input2を持ち、3つの引数をとる簡単なファンクションFunc1を定義します。
function Func1 { [CmdletBinding()] param ( $Input1, [Parameter(ValueFromRemainingArguments=$true)] $Input2, $Input3 ) Write-Host "-Input1 = $Input1(Type=$($Input1.GetType()))." Write-Host "-Input2 = $Input2(Type=$($Input2.GetType()))." Write-Host "-Input3 = $Input3(Type=$($Input3.GetType()))." }
このFunc1に対して3つ以上の引数を指定すると以下の様になり、-Input2に余りの引数がリストの形でまとめられているのがわかります。
この例の様にパラメーター名を指定しない場合は後ろの引数がまとめられます。
(-Input2は2 4 5でなく3 4 5なのに注意してください。)
PS C:\> Func1 1 2 3 4 5 -Input1 = 1(Type=int). -Input2 = 3 4 5(Type=System.Collections.Generic.List[System.Object]). -Input3 = 2(Type=int).
パラメーター名を指定した場合は以下の様になります。
# パラメータ名で割り当てられなかった余りがValueFromRemainingArgumentsを持つパラメータにまとめられる PS C:\> Func1 1 -Input3 2 -Input1 3 4 5 -Input1 = 3(Type=int). -Input2 = 1 4 5(Type=System.Collections.Generic.List[System.Object]). -Input3 = 2(Type=int). # ValueFromRemainingArgumentsを持つパラメータを名前付きで指定するとパラメータの数が合わずエラーとなる PS C:\> Func1 1 -Input2 2 3 4 5 Func1 : 引数 '4' を受け入れる位置指定パラメーターが見つかりません。 発生場所 行:1 文字:1 + Func1 1 -Input2 2 3 4 5 + ~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [Func1]、ParameterBindingException + FullyQualifiedErrorId : PositionalParameterNotFound,Func1
Write-HostとWrite-Outputの表示の違い
ここから本題に入りWrite-HostとWrite-Outputの表示の違いを説明します。
色指定の有無
まずは基本から。
Write-Hostでは-ForegroundColorにより文字の前景色、-BackgroundColorにより背景色を指定することができます。
前回のエントリで説明したとおり、Write-Outputは出力ストリームにオブジェクトを出力するためのものですので色を付けることはできません。

改行の有無
Write-Hostでは-NoNewlineにより文字列表示後に改行をつけるか否かを設定できます。
-NoNewlineはSwitchパラメーターで既定値は$trueです。

Write-Outputにはこのパラメータは無く、常に改行付きの文字列がコンソールに表示されます。

オブジェクトの種類による違い
入力に文字列以外のオブジェクトを指定した場合、Write-Hostでは入力オブジェクトを無条件にToString()した結果が表示されます。

Write-OutputではPowerShellの書式設定に応じた表示となります。
こちらも前回説明した通り、Write-Outputしたオブジェクトは最終的にFormat-*(Format-Default)が呼ばれて書式設定されるためになります。

可変長引数を受けた場合の表示の違い
最初に説明したとおり、Write-HostとWrite-Outputでは可変長の引数を受けることができます。
Write-Hostでは入力値を横並びに表示します。
-Separatorパラメーターで横並びにする際の区切り文字を指定することもできます。

Write-Outputでは入力値を配列にして返します。このため最終的なコンソールへの表示は縦並びとなります。


配列を指定した場合の違い
引数に配列を指定した場合は可変長引数を受けた場合と同様の結果となります。

ハッシュテーブルを指定した場合の違い
引数にハッシュテーブルを指定した場合、Write-Hostはオブジェクトの配列を受けた扱いとなり"System.Collections.DictionaryEntry"の文字列が横並びで表示されます。
Write-Outputではキーと値の内容が表示されます。

補足
一番利用頻度が高いであろう文字列の出力についての詳細はぎたぱそ先生の以下のエントリが非常に有用ですので参考にしてください。