現代のシステム管理やクラウドネイティブな開発において、データの受け渡しに使用されるJSON形式の重要性はますます高まっています。
PowerShellは、このJSON形式を標準機能で直感的に操作できる強力なコマンドレットを備えています。
その中でも、PowerShellオブジェクトをJSON形式に変換するConvertTo-Jsonは、API連携や設定ファイル作成に欠かせない存在です。
2026年現在の最新のPowerShell環境においても、このコマンドレットを正しく使いこなすことは、自動化の効率を左右する重要なスキルと言えるでしょう。
本記事では、ConvertTo-Jsonの基礎から、実務で直面しやすい落とし穴、そして最新のパラメーターを活用した応用テクニックまでを詳しく紹介します。
ConvertTo-Jsonの基本的な役割と使い方
ConvertTo-Jsonは、PowerShell内で扱うカスタムオブジェクトやハッシュテーブルを、標準的なJSON文字列に変換するためのコマンドレットです。
Web APIにデータを送信する際や、プログラム間でのデータ交換を行う際に、オブジェクトの構造を維持したままテキスト形式へ変換する役割を担います。
オブジェクトをJSON文字列に変換する
最も基本的な使い方は、パイプラインを使用してオブジェクトをコマンドレットに渡す方法です。
以下の例では、ユーザー情報を持つカスタムオブジェクトを作成し、それをJSON形式に変換しています。
# カスタムオブジェクトの作成
$user = [PSCustomObject]@{
ID = 101
Name = "Taro Tanaka"
Roles = @("Admin", "User")
IsActive = $true
}
# JSON形式に変換して表示
$user | ConvertTo-Json
{
"ID": 101,
"Name": "Taro Tanaka",
"Roles": [
"Admin",
"User"
],
"IsActive": true
}
このように、数値は数値として、配列は配列として、論理値は小文字のtrue/falseとして適切に変換されることがわかります。
出力結果の整形と圧縮
デフォルトでは、ConvertTo-Jsonは人間が読みやすいように改行とインデントを含んだ状態で出力します。
しかし、ネットワークの帯域を節約したい場合や、ログの1行に収めたい場合には、不要な空白を除去する必要があります。
その際に使用するのが-Compressパラメーターです。
# 空白や改行を除去して1行のJSONにする
$user | ConvertTo-Json -Compress
{"ID":101,"Name":"Taro Tanaka","Roles":["Admin","User"],"IsActive":true}
用途に応じて、読みやすさ重視のデフォルト出力と、効率重視の圧縮出力を使い分けるようにしましょう。
実務で必須となる主要なパラメーター
ConvertTo-Jsonを実務で利用する際、デフォルト設定のままでは意図しない結果を招くことが少なくありません。
ここでは、トラブルを未然に防ぎ、より高度な制御を行うための重要なパラメーターを解説します。
最も重要な「-Depth」パラメーター
ConvertTo-Jsonを使用する上で、最も注意すべきなのが「-Depth」パラメーターの設定です。
PowerShellのJSON変換には「階層の深さ」に関するデフォルトの制限が存在します。
デフォルトの深さは「2」に設定されており、これを超える深い階層を持つオブジェクトを変換しようとすると、下位のデータが文字列(クラス名)に置き換わってしまいます。
# 深い階層を持つオブジェクトの例
$complexObject = @{
Level1 = @{
Level2 = @{
Level3 = @{
Message = "Hello"
}
}
}
}
# デフォルト(Depth 2)で変換
$complexObject | ConvertTo-Json
{
"Level1": {
"Level2": "System.Collections.Hashtable"
}
}
上記の出力結果では、Level2の中身が欠落し、型の名前だけが表示されています。
これを防ぐためには、変換したいデータの構造に合わせて-Depthの値を明示的に指定する必要があります。
# 深さを明示して変換(例:10階層まで許可)
$complexObject | ConvertTo-Json -Depth 10
複雑な設定ファイルや大規模なAPIレスポンスを生成する場合は、常に -Depth パラメーターに十分な値を指定する習慣をつけておきましょう。
配列として常に出力する「-AsArray」
PowerShell 7.5以降などの比較的新しい環境では、-AsArrayパラメーターが非常に便利です。
通常、要素が1つしかない配列をConvertTo-Jsonに渡すと、出力は単一のオブジェクト形式({})になります。
しかし、受け取り側のプログラムが常に配列形式([])を期待している場合、この挙動がバグの原因となります。
# 要素が1つだけの配列
$singleElement = @("Only One")
# デフォルトでは単一要素として出力される可能性がある
$singleElement | ConvertTo-Json
# -AsArray を使うと強制的に配列形式になる
$singleElement | ConvertTo-Json -AsArray
このパラメーターを使用することで、データの数に関わらず一貫性のあるJSON構造を保証できます。
列挙型を文字列にする「-EnumsAsStrings」
PowerShellのオブジェクトには、特定の状態を示す「列挙型(Enum)」が含まれることがあります。
デフォルトでは、列挙型は数値(整数値)としてJSONに変換されますが、これでは人間が読み取ることが難しくなります。
-EnumsAsStringsパラメーターを使用すると、列挙型の値を「”Started”」や「”Stopped”」といった名前の文字列として出力できます。
# サービスの実行状態を取得(Statusは列挙型)
$service = Get-Service | Select-Object -First 1 Name, Status
# 文字列として出力
$service | ConvertTo-Json -EnumsAsStrings
APIの仕様が文字列によるフラグ管理を求めている場合には、このパラメーターが極めて有効です。
データ変換時における注意点とトラブルシューティング
ConvertTo-Jsonは便利ですが、万能ではありません。
データ構造や型によっては、変換時に予期せぬ挙動を示すことがあります。
日付と時刻のフォーマット
PowerShellのDateTimeオブジェクトをJSONに変換すると、デフォルトでは特定の形式で出力されます。
これは多くの場合、ISO 8601形式に近いものですが、環境やPowerShellのバージョンによって微細な差異が生じることがあります。
特定のフォーマットを強制したい場合は、Select-Objectなどを使用して、あらかじめ文字列に変換してからConvertTo-Jsonに渡すのが安全です。
# 日付をあらかじめ文字列に整形してから変換する例
$log = [PSCustomObject]@{
Timestamp = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")
Event = "System Backup"
}
$log | ConvertTo-Json
循環参照によるエラー
オブジェクトが自分自身をプロパティとして持っているような「循環参照」を含むデータを変換しようとすると、ConvertTo-Jsonはエラーを発生させます。
これは無限ループを防ぐための仕様ですが、複雑なシステムオブジェクトをそのまま変換しようとした際に遭遇しやすい問題です。
解決策としては、必要なプロパティのみを Select-Object で抽出してから変換に回すことが挙げられます。
変換における各パラメーターの比較表
状況に応じてどのパラメーターを使うべきか、以下の表を参考にしてください。
| パラメーター | 主な用途 | 注意点 |
|---|---|---|
| -Depth | ネストされた深い構造を正確に変換する。 | 指定を忘れると階層が途切れる。 |
| -Compress | 空白・改行を除去し、データサイズを最小化する。 | 人間にとっては非常に読みにくくなる。 |
| -EnumsAsStrings | Enum値を数値ではなく名前で出力する。 | 受信側が数値のみを期待している場合は注意。 |
| -AsArray | 要素が1つでも必ず配列形式 [] で出力する。 | PowerShell 7系以降で利用可能。 |
| -EscapeHandling | 特殊文字のエスケープ処理を制御する。 | HTMLタグなどを含むデータの扱いに使用。 |
応用的な活用シーン:REST APIとの連携
最も一般的なConvertTo-Jsonの活用シーンは、外部のWebサービス(REST API)へデータを送信するケースです。
Invoke-RestMethodと組み合わせることで、PowerShellから簡単にクラウドサービスを操作できます。
# APIに送信するペイロードの作成
$payload = @{
title = "New Task"
body = "This is a task created by PowerShell"
userId = 1
}
# JSONに変換(Depthを忘れずに指定)
$jsonPayload = $payload | ConvertTo-Json -Depth 5
# APIへPOSTリクエストを送信
Invoke-RestMethod -Uri "https://jsonplaceholder.typicode.com/posts" `
-Method Post `
-Body $jsonPayload `
-ContentType "application/json"
このように、ハッシュテーブルで直感的にデータを構築し、最後にConvertTo-Jsonで整形することで、複雑なJSONリクエストもミスなく作成できます。
設定ファイルの自動生成とバックアップ
ローカル環境の設定を保存するために、JSON形式のファイルを出力するケースも増えています。
ConvertTo-Jsonで生成した文字列をSet-Contentで保存するだけで、再利用可能な設定ファイルが完成します。
# 現在の環境設定をオブジェクト化
$config = @{
LastUpdate = Get-Date
ServerName = $env:COMPUTERNAME
Settings = @{
AutoBackup = $true
LogPath = "C:\Logs"
}
}
# JSONファイルとして保存
$config | ConvertTo-Json -Depth 5 | Set-Content -Path ".\config.json" -Encoding utf8
JSON形式は人間にとっても編集しやすいため、管理者が手動で微調整を行うような運用にも適しています。
特に-Depthを適切に設定して出力することで、複雑な階層構造も確実に永続化できる点が大きなメリットです。
まとめ
ConvertTo-Jsonは、PowerShellと外部システムを繋ぐための極めて重要な架け橋です。
単なる変換コマンドとしてだけでなく、-Depthによる階層の制御や、-Compressによる最適化、そして-AsArrayによる構造の維持など、その特性を深く理解することが求められます。
特に、階層が深いデータを扱う際にデフォルトの制限でデータが欠落する問題は、初心者だけでなくベテランでも陥りやすいポイントです。
常にデータの構造を意識し、適切なパラメーターを選択することで、エラーに強く保守性の高いスクリプトを構築できるようになります。
本記事で紹介したテクニックを活用し、日々の自動化ワークフローをより洗練されたものに進化させていきましょう。
