![PowerShell Write-Host が同期しない](https://rvso.com/image/658747/PowerShell%20Write-Host%20%E3%81%8C%E5%90%8C%E6%9C%9F%E3%81%97%E3%81%AA%E3%81%84.png)
サーバーのいくつかのプロパティを確認するためのPowerShellスクリプトを書いています。次のコマンドレットを実行すると順番に、出力は期待した順序で表示されません。
Write-Host "=== Operating System ==="
Get-WmiObject -computername $ServerName -class Win32_OperatingSystem | select Caption | ft -HideTableHeaders -AutoSize
Write-Host "=== Pagefile ==="
Get-WmiObject -ComputerName $ServerName -Class Win32_PageFileSetting
Write-Host "=== Locale ==="
Get-WmiObject -ComputerName $ServerName -class Win32_OperatingSystem | select Locale | ft -HideTableHeaders -AutoSize | Write-Output
出力:
=== オペレーティング システム ===
Microsoft Windows Server 2012 標準
=== ページファイル ===
=== ロケール ===
最大サイズ 名前 キャプション
----------- ---- -------
4000 C:\pagefile.sys C:\ 'pagefile.sys'0813
Get-WmiObject
ページファイルの出力がタイトルの下に表示されないのはなぜでしょうか?非同期で実行され、すぐに次のタイトル (ロケール) が書き込まれるように思われます。
これを防ぐにはどうしたらいいでしょうか? Write-Output を使用すると機能しますが、色付きのテキストは使用できません。
答え1
画面上のテキストの一部は、PowerShell パイプライン、Write-Host
パイプラインに触れることなくすぐに画面に印刷されるものもあります。
ページファイルに関する WMI 情報を収集するには時間がかかり、パイプラインに出力されますが、そのパイプラインが完了する前に、スクリプトはすでにロケール メッセージの出力に移行しています。
(Operating System) の場合は、この現象は発生しません。このパイプラインはft -AutoSize
(Format-Table) で終了し、スクリプトを一時停止してパイプライン内のすべての処理を待機するため、列のサイズを決定する際にできるだけ多くの情報を得ることができます。ft
画面に出力されたら、スクリプトは PageFile メッセージに移動します。
Write-Output
代わりに、パイプラインを介してテキストを送信するには を使用する必要があります。これにより、リダイレクト、ファイルおよび変数でのコマンド出力の収集などの他の PowerShell 機能と適切に統合されます。
Write-Host
Jeffrey Snover (PowerShell の主任アーキテクト) は、これが推奨されない理由について、自身のブログで次のように書いています。http://www.jsnover.com/blog/2013/12/07/write-host-considered-harmful/
の動作を説明するリンクは次のとおりですFormat-Table
。
列幅の最適化
パイプラインは結果をリアルタイムで処理するため、PowerShell は列要素が占めるスペースの幅を認識できません。その結果、列のサイズは広くなる傾向があります。-AutoSize パラメーターを指定すると、Format-Table はすべての結果を最初に収集してから、すべての要素の最大幅を設定します。出力を最適化できますが、結果はリアルタイムで出力されなくなります。