PowerShellを利用してシステム管理や自動化スクリプトを作成する際、取得したデータを一時的に保存したり、別のセッションで再利用したりしたい場面は多々あります。
PowerShellでは、オブジェクトの構造を維持したままファイルに書き出す方法として、XML形式での保存が標準でサポートされています。
特に「Export-Clixml」と「Import-Clixml」というコマンドレットを活用することで、複雑なデータ構造も簡単に永続化できます。
本記事では、PowerShellオブジェクトをXML形式で保存・復元する具体的な手法と、運用で役立つ活用術を詳しく紹介します。
PowerShellにおけるオブジェクト保存の重要性
PowerShellの最大の特徴は、テキストではなく「オブジェクト」をパイプラインで受け渡す点にあります。
しかし、スクリプトの実行が終了すると、メモリ上に展開されたオブジェクトはすべて破棄されてしまいます。
例えば、数時間かけて収集したサーバーの構成情報や、複雑な計算結果を保持したカスタムオブジェクトを後で分析したい場合、ファイルへの保存が不可欠です。
CSV形式でも保存は可能ですが、CSVは階層構造を持たないフラットなデータ形式であるため、オブジェクトの型情報やネストされたプロパティが失われるという欠点があります。
そこで役立つのが、CLI XML(Common Language Infrastructure XML)形式による保存です。
この形式を利用すれば、オブジェクトのプロパティだけでなく、その型情報まで含めて忠実に再現することが可能になります。
Export-Clixmlによるオブジェクトの出力
オブジェクトをXML形式で保存するには、Export-Clixmlコマンドレットを使用します。
このコマンドレットは、パイプラインから渡されたオブジェクトをシリアル化し、指定したパスにファイルとして保存します。
まずは、簡単なプロセス情報を保存する例を見てみましょう。
# 現在実行中のプロセスから、特定のプロセスを取得して変数に格納します
$proc = Get-Process | Select-Object -First 5
# オブジェクトをXMLファイルとして保存します
$proc | Export-Clixml -Path "C:\temp\process_backup.xml"
Write-Host "オブジェクトの保存が完了しました。"
上記のコードを実行すると、指定したパスにXMLファイルが生成されます。
このXMLファイルの中身を確認すると、単なるテキストではなく、.NETの型情報が含まれた構造化データが記述されていることがわかります。
Export-Clixmlを使用する際の主要なパラメーターは以下の通りです。
| パラメーター名 | 説明 |
|---|---|
| -Path | 保存先ファイルのパスを指定します。 |
| -Depth | オブジェクトをシリアル化する際の階層の深さを指定します(デフォルトは2)。 |
| -Force | 既存のファイルがある場合に上書きを強制します。 |
| -NoClobber | 既存のファイルがある場合に上書きを防止します。 |
特に重要なのが-Depthパラメーターです。
デフォルトの深さは2階層までとなっているため、非常に複雑な階層構造を持つオブジェクトを保存する場合、深い階層のデータが欠落することがあります。
複雑なオブジェクトを扱う際は、必要に応じて-Depthの値を大きく設定することを検討してください。
Import-Clixmlによるオブジェクトの復元
保存したXMLファイルからオブジェクトを元の状態に戻すには、Import-Clixmlコマンドレットを使用します。
このコマンドレットはXMLファイルを読み込み、デシリアライズ(逆シリアル化)を行ってPowerShellオブジェクトとして再構築します。
# 保存したXMLファイルを読み込み、変数に復元します
$importedProc = Import-Clixml -Path "C:\temp\process_backup.xml"
# 復元されたオブジェクトの型と内容を表示します
$importedProc | Select-Object Name, Id, CPU | Format-Table
Name Id CPU
---- -- ---
ApplicationFrameHost 1234 0.5
brave 5678 12.3
conhost 9012 0.1
...
このように、ファイルから読み込んだデータが再びオブジェクトとして操作可能になります。
復元されたオブジェクトは、プロパティへのアクセスやWhere-Objectによるフィルタリングなど、通常のオブジェクトと全く同じように扱うことができます。
デシリアライズされたオブジェクトの注意点
XMLから復元されたオブジェクトには、一つ重要な特性があります。
それは、復元されたオブジェクトが「デシリアライズされた(Deserialized)」状態であるという点です。
本来のオブジェクト(例えばSystem.Diagnostics.Process)が持っていた「メソッド」は、復元後のオブジェクトでは利用できません。
例えば、Get-Processで直接取得したオブジェクトにはプロセスを終了させるKill()メソッドが存在しますが、XMLから復元したオブジェクトで$importedProc.Kill()を呼び出すことはできません。
復元されたオブジェクトは、あくまで保存時点のプロパティ(値)を保持した「データセット」であると認識しておく必要があります。
型名を確認すると、元の型名の前にDeserialized.という接頭辞が付与されていることが確認できるはずです。
# 型名を確認する
$importedProc[0].GetType().FullName
Deserialized.System.Diagnostics.Process
このように、メソッドは消失しますが、プロパティの構造や値は正確に復元されるため、レポート作成や過去データとの比較用途には最適です。
カスタムオブジェクト(PSCustomObject)の保存と復元
運用スクリプトでは、自分で作成したPSCustomObjectを保存したいケースが多いでしょう。
Export-Clixmlはカスタムオブジェクトとも非常に相性が良く、複数の属性を持つ独自のデータ構造をそのまま保持できます。
# カスタムオブジェクトを作成します
$mySetting = [PSCustomObject]@{
ServerName = "SV-Web01"
IPAddress = "192.168.1.10"
Status = "Active"
Tags = @("Production", "Web", "Japan")
Timestamp = Get-Date
}
# XML形式で保存します
$mySetting | Export-Clixml -Path "C:\temp\server_setting.xml"
# 保存したデータを読み込みます
$restoredSetting = Import-Clixml -Path "C:\temp\server_setting.xml"
# 配列型のプロパティも正しく復元されているか確認します
$restoredSetting.Tags[0]
Production
上記の例のように、配列(Tagsプロパティ)や日時情報(Timestampプロパティ)が含まれていても、型が適切に処理された状態で復元されます。
これはJSON形式で保存した際に行われる「日付が文字列に変換される」といった現象を防ぐことができる大きなメリットです。
認証情報の安全な保存:PSCredentialの扱い
Export-Clixmlの特筆すべき機能の一つに、資格情報(PSCredentialオブジェクト)のセキュアな保存があります。
通常、パスワードを含むオブジェクトをファイルに保存するのはセキュリティ上のリスクが伴います。
しかし、PowerShellのCLIXMLエクスポート機能は、Windowsのデータ保護API(DPAPI)を使用して資格情報を暗号化します。
# 資格情報プロンプトを表示して取得します
$cred = Get-Credential
# 資格情報をXMLに保存します(パスワード部分は暗号化されます)
$cred | Export-Clixml -Path "C:\temp\secure_cred.xml"
この方法で保存されたXMLファイル内のパスワードは、保存したユーザーかつ保存したコンピューター上でのみ復号が可能です。
他のユーザーがこのファイルをコピーして読み取ろうとしても、暗号化を解除できないため、パスワードが漏洩するリスクを低減できます。
ただし、同じユーザー権限を持つスクリプトであれば復号できてしまうため、ファイルのアクセス権限設定(ACL)も併用して管理することが推奨されます。
JSONやCSVとの比較
データ保存の形式には他にもCSVやJSONがありますが、どのように使い分けるべきでしょうか。
それぞれの特徴を比較した表を以下に示します。
| 特徴 | CLIXML | JSON | CSV |
|---|---|---|---|
| 型情報の維持 | 非常に高い | 中程度(一部消失) | 低い(すべて文字列) |
| 階層構造の保持 | 完全対応 | 完全対応 | 非対応 |
| 他言語との互換性 | 低い(PowerShell専用) | 非常に高い | 非常に高い |
| 可読性(人間による) | 低い(タグが多い) | 高い | 高い |
| セキュリティ(暗号化) | 資格情報に対応 | 非対応 | 非対応 |
「PowerShell環境内でのみ完結するデータ保存」であれば、CLIXMLが最も優れた選択肢となります。
一方で、Pythonなどの他言語とデータを共有したり、Web APIのペイロードとして利用したりする場合は、JSON形式を選択するのが一般的です。
また、Excelで開いて編集したいような単純なリストデータであれば、CSV形式が適しています。
大量のオブジェクトを扱う際のパフォーマンス
Export-Clixmlは非常に便利な一方で、シリアル化とデシリアル化に一定の計算リソースを消費します。
数万件を超えるような大量のオブジェクトを一度に処理する場合、XMLファイルのサイズが肥大化し、読み書きに時間がかかることがあります。
もしパフォーマンスが課題となる場合は、保存する前にSelect-Objectを使用して、本当に必要なプロパティだけに絞り込む処理を挟んでください。
不要なプロパティをあらかじめ削ぎ落としておくことで、XMLの構造がシンプルになり、処理速度の向上が期待できます。
まとめ
PowerShellにおいて、オブジェクトをXML形式で保存・復元するExport-ClixmlおよびImport-Clixmlは、データの一時保存や自動化の効率化に欠かせないツールです。
CSVやJSONでは損なわれがちな型情報や階層構造を維持できるため、複雑なデータを扱うエンジニアにとって非常に強力な味方となります。
特に資格情報の暗号化保存は、セキュアな自動化スクリプトを作成する上で欠かせないテクニックです。
ただし、復元されたオブジェクトにはメソッドが含まれない点や、独自の型名(Deserialized)になる点には留意が必要です。
本記事で紹介した「深さ(Depth)」の指定や適切な形式の使い分けを意識することで、より堅牢でメンテナンス性の高いスクリプト開発が可能になります。
ぜひ日々の運用業務に、この強力なXML活用術を取り入れてみてください。
