PowerShellのConvertTo-Jsonで入れ子が消える?Depthを変えて構造を観察する

PowerShellカテゴリを表すパンダのイラスト PowerShell

この記事について
この記事は、生成AIを活用した自動生成フローで作成しています。Microsoft LearnのConvertTo-JsonとConvertFrom-Jsonの仕様を根拠に、架空の備品データを使った再現手順と判断方法を整理しました。

検証ステータス:📘 公式仕様を参照・PowerShell実機での操作未実施

PowerShellのConvertTo-Jsonで入れ子が消える?Depthを変えて構造を観察する

PowerShellでJSONを作るとき、画面上では部署名も担当者も表示されるのに、保存したJSONを別のシステムへ渡すと途中の情報が文字列に変わってしまうことがあります。特に設定ファイルやAPIへの送信データを組み立てる際、見た目だけで正常と判断するのは危険です。原因候補の一つが、ConvertTo-Json の -Depth です。今回は外部サービスを呼ばず、メモリ内の架空データで階層と変換結果の関係を観察します。

まず何が起きるか

例えば総務部が備品管理用のJSONを作り、別の担当者に引き渡す場面を考えます。備品の名前だけでなく、管理部署、その部署の連絡先まで一つのデータにまとめたいとします。PowerShellではハッシュテーブルを入れ子にすれば自然に表現できます。しかし、JSONへ変換するときの深さ制限は、PowerShell上のデータ構造の深さとは別に指定されます。変換後のJSONが構文として正しいことと、必要な属性が残っていることも別問題です。

ここで確かめたいのは、Depth を変えると単に文字数が増えるのか、それともオブジェクトの構造そのものが変わるのか、という点です。予想を立ててから二つの結果を比べてください。実行するのはPowerShell 7系を想定した短いコードで、管理者権限やネットワーク接続は不要です。

安全な実験:同じデータを二度変換する

PowerShell 7を開き、以下を一つのブロックとして実行します。業務の本物の連絡先やAPIトークンは入れず、名前も電話番号も架空のものだけを使います。コードはファイルを作らず、画面へ文字列を出力するだけです。

$item = @{
    item = '架空ノートPC'
    owner = @{
        department = '総務'
        contact = @{
            name = '担当A'
            extension = '0000'
        }
    }
}

'=== depth 2 ==='
$item | ConvertTo-Json -Depth 2
'=== depth 5 ==='
$item | ConvertTo-Json -Depth 5

注目するのは、owner の内側にある contact がJSONオブジェクトとして残るかどうかです。既定の深さは2です。深さが足りない場所では、元のオブジェクトが期待した入れ子のJSONとして表現されず、文字列化される場合があります。PowerShell 7.1以降では指定した深さを超える場合に警告が出る仕様もあります。警告の有無だけでなく、変換結果の引用符と波括弧を観察してください。

-Depth 5 にした側では、今回の比較的小さな入れ子はJSONのオブジェクトとして表現される想定です。ただし、掲載しているのは仕様から導いた期待挙動であり、この記事の制作時にWindows上のPowerShellを実行して得た実測ログではありません。実行したら両方の出力を並べ、contact の直後に波括弧があるか、単一の引用符付き文字列になっていないかを確かめます。

図で見る:データとJSON化の境界

次の図は、PowerShellの入れ子構造をJSONへ変換するとき、深さ指定がどこで効くかを示したものです。左側のデータが同じでも、変換の条件が違えば出力の構造は変わります。図の分岐は今回の理解のための概念図であり、PowerShell内部実装の関数呼び出し順を断定するものではありません。

flowchart TD
    A["入れ子のPowerShellオブジェクト"] --> B["ConvertTo-Json"]
    B --> C{"Depthは十分か"}
    C -->|はい| D["入れ子をJSONオブジェクトとして表現"]
    C -->|いいえ| E["深い部分が期待どおりの構造にならない"]
    D --> F["受け手がキーをたどれる"]
    E --> G["構造を確認しDepthを見直す"]

この図で重要なのは、JSONの構文検査に成功しても、右側の受け手が期待するキーをたどれるとは限らないことです。例えばowner.contact.nameという階層を前提とする処理では、contactが文字列になっていると、その下のnameというキーを取り出せません。送信先の障害を疑う前に、送信前のJSONを調べる理由がここにあります。

もう一歩:JSONから戻して構造を確かめる

画面の文字列を目で眺めるだけでは、引用符やエスケープを見落とすことがあります。変換結果をもう一度PowerShellのオブジェクトへ戻し、対象の値が文字列なのか、属性を持つオブジェクトなのかを確かめると判断しやすくなります。次の例では十分な深さを指定したJSONを再読込し、担当者名を取得します。

$json = $item | ConvertTo-Json -Depth 5
$restored = $json | ConvertFrom-Json
$restored.owner.contact.name
$restored.owner.contact.GetType().FullName

期待する担当者名は担当Aです。型名の表示は実行環境と変換後のオブジェクト表現に依存するため、固定文字列を合格条件にはしません。重要なのは、contactが単なる文字列ではなく、nameを参照できる構造として復元されることです。もし$restored.owner.contact.nameが空になっても、直ちにJSON全体が空だったと判断しないでください。元のJSONでその位置がオブジェクトなのか文字列なのかを調べるのが先です。

ConvertFrom-JsonはJSONの内容を読み取る処理で、元のPowerShellオブジェクトの型や細かな性質を完全に復元するための一般的なシリアライザではありません。ここでは、JSONの受け手から見たキーの階層が維持されているかを調べる道具として使っています。元の型との完全一致を目的とするテストとは分けて考えます。

1条件だけ変える:Depthを増やすと何が改善するか

最初のコードの-Depth 2だけを-Depth 5に変えます。入力データやPowerShellのバージョン、変換先は変えません。これなら出力の差が深さ指定によるものだと考えやすくなります。変換結果が長くなることだけを成功条件にせず、owner、contact、nameという三つの階層をJSONのキーとして追えるかを確認します。

一方、無条件に非常に大きな数を指定すれば安心というわけでもありません。深さが増えれば、意図していなかった内部データまで出力対象になる可能性があります。API送信用のJSONなら、必要なキーだけを新しいハッシュテーブルに明示的に組み立てるほうが、入力オブジェクト全体をそのまま変換するより安全な場合があります。必要な階層を数え、想定したスキーマに合う値を設定してください。

この比較で分かるのは、Depthが「画面へ何行表示するか」という設定ではなく、変換時にどこまで入れ子を扱うかを決める設定だということです。変換前のPowerShellの値が正しくても、出力形式を決める段階で情報の形が変わり得ます。データ連携の不具合では、入力と出力の間にある変換条件を調べる視点が役立ちます。

失敗したときの切り分け

最初に確認したいのは、PowerShell自体がエラーを出しているのか、それともJSONは作れたが期待した構造になっていないのかです。前者ならエラーメッセージとバージョンを記録します。後者なら、JSONの対象部分を取り出して引用符と波括弧を確認します。どちらも原因が同じとは限らないため、対処を混ぜないことが重要です。

次に、実際に指定した-Depthの値とPowerShellのバージョンを確認します。既定値に頼っていた場合は、明示指定に変えて差を比べます。PowerShell 7.1以降の警告についても、表示が見えなかったことを「深さが十分だった証拠」として扱わないでください。警告の扱いやホストの表示方法に左右されるため、出力の構造を直接検査するほうが確実です。

それでも想定どおりにならない場合は、元データに同じ名前のキーがないか、$nullが混ざっていないか、配列と単一オブジェクトを取り違えていないかを調べます。深さを変えても直らない不具合までDepthのせいにすると、別の問題を見逃します。まず対象の最小データだけを残し、不要な属性を外した状態で再現できるか確認するのが安全です。

また、JSONの構文が正しいことを確認するだけでは不十分です。受け手が必要とするキー、値の型、配列かオブジェクトかという形まで確かめてください。JSONはただの文字列ではなく、データ構造を受け渡すための形式です。値が読めるかどうかだけでなく、受け手がその値へ期待した経路で到達できるかが実務上の合格条件になります。

業務で使うときの判断

例えばMicrosoft GraphなどのAPIへJSONを送る処理では、送信先のエラーだけを追う前に、ローカルで作ったリクエスト本文の形を確かめます。ただしAPIごとに必須キーや型は異なるため、今回のサンプルがそのままAPIで利用できるという意味ではありません。APIの仕様に合わせた専用のデータ構造を作り、必要な階層だけを変換する設計を優先します。

設定ファイルを出力する場合も同じです。まず架空のデータで出力し、JSONを読み直して必要な階層が残っていることを確認します。その後で実データに適用します。機密情報を含むデータを画面やログにそのまま表示しないことも大切です。調査のためのJSON表示が、逆に認証情報や個人情報の漏えいにつながらないようにします。

処理を自動化するなら、変換後に必須のキーが存在するかを検査してから次へ進めます。JSONを作れたというだけで正常終了にせず、必要な構造を検査するのが要点です。想定したキーがない場合は送信や上書きを中止し、サンプルの階層と変換条件を見直します。実ファイルの置換やAPIへのPOSTを、この学習用コードで実施する必要はありません。

最後に覚えておきたいのは、問題の場所を三つに分けることです。PowerShellの元データが正しいか、JSONへの変換で形が保たれたか、受け手の仕様に合っているか。これを順に調べれば、単に-Depthを大きくするだけの場当たり的な対処から、再現可能なデータ連携の検証へ進めます。

まとめ

ConvertTo-Jsonの-Depthは、JSONの見た目を整えるだけのオプションではありません。入れ子の構造を保持するために重要な設定です。同じ架空データで深さを一つ変え、出力したJSONをConvertFrom-Jsonで読み戻すと、受け手が期待するキーへ到達できるかを確認できます。深さの指定、出力の構造、送信先のスキーマを分けて検査することが、実務での失敗を減らす近道です。

公式資料・一次情報

  • Microsoft Learn — ConvertTo-Json: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/convertto-json

  • Microsoft Learn — ConvertFrom-Json: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/convertfrom-json

文書情報

記事タイトル
PowerShellのConvertTo-Jsonで入れ子が消える?Depthを変えて構造を観察する
作成日
更新日
Source URL
https://papanda925.com/?p=18564

ライセンス: 本記事のうち、当サイトが権利を有する本文・自作図表は、特記なき限り CC BY 4.0 で利用できます。生成AIを活用して作成・編集した内容を含みます。コードについて、別途ライセンス表示またはリンク先GitHubリポジトリのライセンスがある場合は、その条件を優先します。引用・第三者資料・画像・商標等は本ライセンスの対象外です。 利用ポリシー

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