コマンドレットのパラメータを列挙してみる。2017の10日目です。PowerShellはオブジェクトを扱うシェルですが、別にテキストデータを扱えない訳ではありません。PowerShellで取得したデータをテキストファイルとして保存したり、スクリプトで用いるデータをテキストファイルで保存しておくことは日常的に行われることだと思います。PowerShellで扱うデータはオブジェクトであり、テキストファイルは文字通り文字列であることから、コマンドレットを用いる等、何らかの手段で変換が必要になります。テキストデータ形式にも様々な種類があり、それぞれメリット、デメリットが存在します。今回の記事では、PowerShellで用いるデータを保持しておく際のテキストデータ形式について比較をしてみます。プレーンテキストプレーンテキスト、すなわち書式なしのテキストファイルです。シンプルな使い方をする場合、文字列配列の各要素に含まれる文字列が、テキストファイルの1行と対応します。UTF8$linesは文字列変数です。理由がなければ文字コードはUTF-8で良いと思います。UTF8Add-Contentは実行のたびにファイルを開いて、書き込んでから閉じるという動作をするので、1行ずつforeachで実行するのはNGです。UTF8)メリット文字列配列をテキストファイルに書き出すのは多分これが一番楽だと思います。書き出したデータは人間にも読みやすい。デメリット文字列だけを保存しておきたいというケースがそもそも少ない。CSVコンマ等の特別な文字で区切り、1行あたりに複数のデータを保存できる形式です。PowerShellのコマンドレットで扱う場合、オブジェクトが持つプロパティがヘッダ列名に対応します。各行にオブジェクト配列1要素のプロパティ値が、カンマ区切りで保持されます。Default$objectsは任意のオブジェクト配列です。必要であればSelect-Objectコマンドレットを併用して、プロパティを絞り込みます。文字コードはExcelでそのまま読み込み/書き出しができるDefault(日本語環境ではShift_JIS)がお勧めです。Defaultメリットオブジェクトのプロパティ値が、すべて数値あるいは文字列で表現できる値を持つ場合に最も適合する。人間にも読みやすく、ある程度は編集もできる。デメリットオブジェクトのプロパティが、数値と文字列以外のオブジェクトである場合、すなわち、階層構造を持つデータの保存には適さない。数値も文字列として読み込まれてしまうので、数値として扱いたい場合は変換が必要になる。Export-CsvとImport-Csvで扱うCSVファイルはヘッダが必須。ヘッダなしのCSVファイルが既にあって、それを読み書きするという用途には適さない。(できなくはないが)書き出し時の列順を制御することができない。PowerShellで書き出したCSVを、列順が固定であるとの想定である他のプログラムで読み込むことは基本NG。書き出し時、1つ目の要素に存在しないプロパティは、2つ目以降では存在しないものとして扱われる。同種のオブジェクトで構成される配列なら通常は問題ないのだが、要素によって動的に追加されるプロパティがあったりなかったりすると厄介。(ADでありがち)JSONJavaScriptのような表記でデータを保持するデータ形式です。データの受け渡しに様々な言語で利用できます。APIでもよく利用されます。PowerShellではv3からJSONを扱うコマンドレットが提供されています。ConvertFrom-JsonメリットCSVと異なり、階層構造を持ったデータでも扱える。CSVと異なり、数値は数値型のまま読み書き可能。(整数値はint、小数値はdecimal)人間にもまぁまぁ読めるし、頑張れば編集できなくもない。デメリット-Depthパラメータによりプロパティを展開する階層の深さを指定はできるが、プロパティに応じて深さ指定を変化させるというようなことはできない。基本的には、自分で構築したPSCustomObjectを使うか、JSON化する前に自分で元オブジェクトを整形しておく必要がある。直接ファイルに書き出し、追記、ファイルから読み込みするコマンドレットはない。実は細かい話をしだすと色々と罠があります...。CLIXMLPowerShellではPSリモーティング等、プロセス間でオブジェクトのやり取りを行う際に、CLIXML形式を介してシリアライズ/デシリアライズが実行されます。シリアライズ対象によっては、完全に元のクラスのオブジェクトに復元されます。(復元されないオブジェクトにはクラス名にDeserialized.との接頭辞が付与され、プロパティ値のみ復元される)ユーザーもコマンドレットを用いて、任意のデータをCLIXML形式でシリアライズし、XMLファイルとして保存することができます。file.xmlメリット元のオブジェクトの構造、プロパティ値と型情報を含めてほぼ完全にテキストファイルに保存できる。復元したオブジェクトはプロパティ値を参照できるのはもちろん、オブジェクト全体が完全にデシリアライズされ、元の型に戻った場合には、メソッドを実行することも可能。元の型に戻らず、Deserialized.との接頭辞が付いた状態でも、コンソールに表示する場合は元の型のフォーマットが使われるので見やすい。デメリットすべてのオブジェクトが元の型に戻せるわけではない。戻せるかどうかは確認が必要。人間が読み書きするようなものではない。ちなみに、ConvertTo-Xmlという似たようなコマンドレットがありますが、出力形式はCLIXMLではない上、復元の手段もなく、かといって別に読みやすいXMLというわけでもなく、正直何のために使うのかよく分かりません(適切なxsltでも用意すればいいのかな?)。ConvertTo-Htmlの方が使えそうです。psd1psd1は「PowerShellデータファイル」で、モジュールマニフェストやローカライズデータに使われるファイル形式です。コメントなど基本的な言語要素のみ使用可能です。5.0以降ではImport-PowerShellDataFileコマンドレットを用いて、任意のpsd1ファイルのデータを読み込み、変数に格納することが可能です。書き出し書き出し用のコマンドレットはありません。読み込み例えば以下のような内容をbackup_setting.psd1として保存しておきます。ルート要素は必ず連想配列にします。"0:00"}なお、dataセクションで全体を括ってもいいですが、psd1で許容される言語要素はdataセクションより更に制限がきついので、敢えてしなくてもいいんじゃないかと思います。このファイルは以下のように読み込めます。backup_setting.psd1$settingには連想配列が格納され、以下のように値が参照できます。$_.To}メリットPowerShellの構文でデータを記述できる。通常のps1ファイルを呼び出すのとは異なり、式の評価やコマンド実行などはされない分、セキュアである。配列と連想配列の組み合わせにより、JSONライクな階層構造を持てる。JSONとは違い、コメントが入れられる。デメリット記述できるデータはプリミティブなものだけ。スクリプトから書き出すためのコマンドレットがない。一応、下位バージョンでやる方法はあります。まとめPowerShellで扱うデータをテキストファイルとして保存する際には、各テキストデータ形式の特性を理解し、メリット、デメリットを踏まえて選定する必要があります。当然ながらテキストファイルに保持することが不適切なデータもありますので、そこは注意してください。(画像データを敢えてBase64とかでエンコードしてテキストファイル化する意味があるのか、とかですね)個人的には...ちょっとした作業ログ等を記録しておきたい→プレーンテキスト.NETオブジェクトの一部のプロパティだけ抜き出してファイル化したい→CSV自分で構築したPSCustomObjectをファイル化したい→JSON.NETオブジェクト全体をファイル化したい→CLIXMLスクリプトで使う設定データを用意したい→psd1みたいな感じでなんとなく使い分けていると思います。psd1はまだ採用例はないですが...。今回はビルトインのコマンドレットで扱えるもののみ取り上げましたが、他にもyaml等のテキストデータ形式が存在し、有志によるモジュールを用いて扱うことが可能です。@mutaguchiBooks書籍版。