【PowerShell】Export-CsvとFormat-Tableは併用できない

PowerShellでファイルの最終更新日時を取得した際に、Format-Tableで列を入れ替えてからExport-CsvでCSV出力しようとしたら想定外の結果になりました。

Export-CsvとFormat-Tableを併用した場合(失敗)

> Get-ChildItem * -Recurse -File -Include *.txt |
  Select-Object Name, DirectoryName, LastWriteTime |
  Sort-Object -Property @{ Expression = 'LastWriteTime'; Descending = $true }, Name |
  Format-Table -Property LastWriteTIme, Name, DirectoryName |
  Export-Csv -Encoding Default -Path C:\work\update-list.csv

結果

#TYPE Microsoft.PowerShell.Commands.Internal.Format.FormatStartData
"ClassId2e4f51ef21dd47e99d3c952918aff9cd","pageHeaderEntry","pageFooterEntry","autosizeInfo","shapeInfo","groupingEntry"
"033ecb2bc07a4d43b5ef94ed5a35d280",,,,"Microsoft.PowerShell.Commands.Internal.Format.TableHeaderInfo",
"9e210fe47d09416682b841769c78b8a3",,,,,
"27c87ef9bbda4f709f6b4002fa4af63c",,,,,
"27c87ef9bbda4f709f6b4002fa4af63c",,,,,
"27c87ef9bbda4f709f6b4002fa4af63c",,,,,
"27c87ef9bbda4f709f6b4002fa4af63c",,,,,
以下、割愛

Export-CsvとFormat-Tableを併用しない場合(成功)

> Get-ChildItem * -Recurse -File -Include *.txt |
  Select-Object Name, DirectoryName, LastWriteTime |
  Sort-Object -Property @{ Expression = 'LastWriteTime'; Descending = $true }, Name |
  Export-Csv -Encoding Default -Path C:\work\update-list.csv

説明(公式ページの転載)

これは公式のExport-Csvコマンドレットのページに記載あります。(以下抜粋)

パイプライン内の Format コマンドレットによって予期しない結果が作成される

この例では、パイプライン内で format コマンドレットを使用しないことが重要である理由を示します。 予期しない出力が受信されたら、パイプライン構文のトラブルシューティングを行います。

Get-Date | Select-Object -Property DateTime, Day, DayOfWeek, DayOfYear |
 Export-Csv -Path .\DateTime.csv -NoTypeInformation
Get-Content -Path .\DateTime.csv

"DateTime","Day","DayOfWeek","DayOfYear"
"Wednesday, January 2, 2019 14:59:34","2","Wednesday","2"

Get-Date | Format-Table -Property DateTime, Day, DayOfWeek, DayOfYear |
 Export-Csv -Path .\FTDateTime.csv -NoTypeInformation
Get-Content -Path .\FTDateTime.csv

"ClassId2e4f51ef21dd47e99d3c952918aff9cd","pageHeaderEntry","pageFooterEntry","autosizeInfo", ...
"033ecb2bc07a4d43b5ef94ed5a35d280",,,,"Microsoft.PowerShell.Commands.Internal.Format. ...
"9e210fe47d09416682b841769c78b8a3",,,,,
"27c87ef9bbda4f709f6b4002fa4af63c",,,,,
"4ec4f0187cb04f4cb6973460dfe252df",,,,,
"cf522b78d86c486691226b40aa69e95c",,,,,

コマンドレットは Get-Date DateTime オブジェクトを取得します。 オブジェクトは、パイプラインからコマンドレットに Select-Object 送信されます。 Select-Objectでは、Property パラメーターを使用してオブジェクト プロパティのサブセットを選択します。 オブジェクトは、パイプラインからコマンドレットに Export-Csv 送信されます。 Export-Csv は、オブジェクトを CSV 形式に変換します。 Path パラメーターは、ファイルが現在のDateTime.csvディレクトリに保存されることを指定します。 NoTypeInformation パラメーターは、csv 出力から #TYPE 情報ヘッダーを削除します。PowerShell 6 では必要ありません。 このコマンドレットではGet-Content、Path パラメーターを使用して、現在のディレクトリにある CSV ファイルを表示します。

パイプライン内でコマンドレットを Format-Table 使用してプロパティを選択すると、予期しない結果が受信されます。 Format-Tableは、DateTime オブジェクトではなく、パイプラインの下にExport-Csvテーブル形式オブジェクトを送信します。 Export-Csv は、テーブル形式オブジェクトを一連の CSV 文字列に変換します。 このコマンドレットは Get-Content 、テーブル形式オブジェクトを含む CSV ファイルを表示します。

参考

タイトルとURLをコピーしました