

### 前提・実現したいこと

PSCustomObjectでjsonファイルをConvertFrom-
Jsonで読み込み、値を追加して、以下のような形で出力したいのですが、どのようなコマンドを実行すれば良いかわかりません。

**InputJson**

[code]

    {
        "hoge1": {
            "hoge2": [
                {
                    "hoge3": [
    
                            ]
                }
             ]
           }
    
    
[/code]

**OutputJson**

[code]

    {
        "hoge1": {
            "hoge2": [
                {
                    "hoge3": [
                               {"foo1": {
                                   "foo2":"XXXX",
                                   "foo3":"XXXX", 
                                        }
                               }
                            ]
                }
             ]
           }
    
[/code]

### 試したこと

foo2、foo3の「key:value」については、以下のコマンドで実施できました。  
しかし、foo1(jsonで言うところのオブジェクト)の部分が追加方法がわかりません。

[code]

    $d = New-Object 'system.collections.generic.dictionary[string,string]'
    $d.Add("foo2","XXXX")
    $d.Add("foo3","XXXX")
    $PSCustomObject.hoge1.hoge2.hoge3 += $d
    
[/code]


CC BY-SA 4.0
2019-11-13T14:05:55.440
60486
2022-05-30T15:04:10.450
2020-06-14T16:47:00.807
3060
36607
question
json powershell
PSCustomObject を用いて既存の JSON ファイルに値を追加したい


完全なJson構造体ではなく、あくまでもPSCustomObjectとして利用するということで良いのでしたら以下で再現可能かと考えます。これで要件に足りますでしょうか？

[code]

    $base = @"
    {
        "hoge1": {
            "hoge2" : ""
        }
    }
    "@
    
    $child = @"
    {
        "hoge3" : ""
    }
    "@
    
    $grandchild = @"
    {
        "foo1" : {
            "foo2" : "XXXX",
            "foo3" : "XXXX"
        }
    }
    "@
    
    $json1 = ConvertFrom-Json $base
    $json2 = ConvertFrom-Json $child
    $json3 = ConvertFrom-Json $grandchild
    
    $json1.hoge1.hoge2 = @($json2)
    $json1.hoge1.hoge2[0].hoge3 = @($json3)
    
[/code]

> 出力  
>  PS C:\Windows\System32> $json1.hoge1.hoge2[0].hoge3[0].foo1.foo2  
>  XXXX

Json構造体として保存したりする必要がある場合、途中の配列がConvertTo-
Json出来ませんので、別途クラス化してJsonQueryStringConverterで変換するか、XMLで構成してJsonReaderWriterFactoryで相互変換可能な様にするか、配列部分のみ自力でコンバートする仕組みを組み込むかのいずれかの方法になるかなと思います。（もっと素敵なアイディアがあるかも知れませんが、今私が思いつくのはこれらの方法です）


CC BY-SA 4.0
2020-06-13T05:24:53.073
67614
2020-06-13T05:24:53.073
19048
60486
answer


こうじゃないすか？

[code]

    $x=cat j.json|ConvertFrom-Json
    $d=new-object "system.collections.generic.dictionary[string,string]"
    $d.add("foo2","XXXX")
    $d.add("foo3","xxxx")
    $foo1=[PSCustomObject]@{"foo1"=$d}
    $x.hoge1.hoge2[0].hoge3=@($foo1)
    $x |ConvertTo-Json -Depth 100 >> j2.json
    
[/code]


CC BY-SA 4.0
2020-06-13T22:37:42.423
67637
2020-06-13T22:37:42.423
17106
60486
answer

[code]

    $PSCustomObject = Get-Content ./input.json | ConvertFrom-Json
    $PSCustomObject.hoge1.hoge2[0].hoge3 += @{ foo1=@{ foo2='XXXX'; foo3='XXXX' } }
    ConvertTo-Json $PSCustomObject -Depth 100
    
[/code]

で実現できます。

* * *

PowerShellはデータ型に拘りません。  
正確には.NETの`System.Object[]`配列なので、どのようなデータ型でも混ぜることができます。また、[`ConvertTo-
Json`はNoteに書かれている](https://docs.microsoft.com/en-
us/powershell/module/microsoft.powershell.utility/convertto-
json?view=powershell-5.1#notes)ように`JavaScriptSerializer`を使います。`JavaScriptSerializer`は任意のオブジェクトを受け付けパブリックプロパティをJSON形式で出力します。結果的に、望む形式でパブリックプロパティを持ってさえいれば型はなんでも良いということになります。  
例えば`PSCustomObject`を使った場合は

[code]

    [PSCustomObject]@{ foo1=[PSCustomObject]@{ foo2='XXXX'; foo3='XXXX' } }
    
[/code]

と書けます。しかしもう１点、`JavaScriptSerializer`は`IDictionary`を持つクラスに対してはJSONのobject型として期待される通りの形で展開されます。そのため

[code]

    @{ foo1=@{ foo2='XXXX'; foo3='XXXX' } }
    
[/code]

で十分な結果が得られます。


CC BY-SA 4.0
2020-06-14T02:18:26.287
67640
2020-06-14T09:50:56.097
2020-06-14T09:50:56.097
19110
4236
60486
answer