Edition: Windows 10 Enterprise
Version: 1607
OS Build: 14393.187
Installed RAM: 16.0 GB
System Type: 64-bit operating system, x64-based processor
[{
"name": "Animals",
"age": "1",
"children": [{
"name": "mimi",
"age": "1",
"lovely": true,
"height": 20
},
{
"name": "dog",
"age": "2",
"lovely": false,
"height": 100
}]
}]
$o=(Get-Content -Raw D:\Test_Convert.json | ConvertFrom-Json)
Set-Content 'D:\result.json' ($o | ConvertTo-Json)
{
"name": "Animals",
"age": "1",
"children": [
{
"name": "mimi",
"age": "1",
"lovely": true,
"height": 20
},
{
"name": "dog",
"age": "2",
"lovely": false,
"height": 100
}
]
}
Get the right PSObject and write the same content back.
The array turns into its only child.
Included in the repro steps.
PS C:\Users\qisun\Downloads\LatestPowerShell> $PSVersionTable.PSVersion
Major Minor Patch Label
----- ----- ----- -----
6 0 0 alpha
Have to mention that the issue does not repro when there are multiple children in that array.
@Francisco-Gamino I think you had brought this up before and this was "by design"?
With the repro as is, it does look like it is by design - we enumerate objects written to the pipeline, so piping loses the fact that the object was an array. This is similar to the difference between:
$o = @(1)
$o | Get-Member
Get-Member -InputObject $o
I was going to suggest using:
Set-Content 'D:\result.json' (ConvertTo-Json -InputObject $o)
But this doesn't work either, and I would consider this a bug.
Just ran into this the other day, the workaround I'm using is
Set-Content 'D:\result.json' (ConvertTo-Json -InputObject @($o))
The fact that it still won't work in pipeline is annoying. I have a restriction that I have to use pipeline, so I end up doing:
.\Some-Script.ps1 -OutVariable List | Out-Null; ConvertTo-Json -InputObject @($List)
And that works. I'm restricted because in this context, the script reference must be first and all other arguments are appended afterwards. I almost want a -AsArray
switch or something to ConvertTo-Json.
.\Some-Script.ps1 | ConvertTo-Json -AsArray
The pipleline issue is by design; however, this is not documented, so I've create an doc issue for this: https://github.com/PowerShell/PowerShell-Docs/issues/1219
For the ConvertTo-Json -InputObject $array, I cannot get it to repro. Here is what I am running:
# Generate a test file with Json content
'[{
"name": "Animals",
"age": "1",
"children": [{
"name": "mimi",
"age": "1",
"lovely": true,
"height": 20
},
{
"name": "dog",
"age": "2",
"lovely": false,
"height": 100
}]
}]' | Out-File Test_Convert.json
# Create the test object from the Json file
$o=(Get-Content -Raw Test_Convert.json | ConvertFrom-Json)
$o
name age children
---- --- --------
Animals 1 {@{name=mimi; age=1; lovely=True; height=20}, @{name=dog; age=2; lovely=False; height=100}}
# Serialize the object using ConvertTo-Json -InputObject
Set-Content result.json (ConvertTo-Json -InputObject $o -Depth 3)
Get-Content .\result.json
[
{
"name": "Animals",
"age": "1",
"children": [
{
"name": "mimi",
"age": "1",
"lovely": true,
"height": 20
},
{
"name": "dog",
"age": "2",
"lovely": false,
"height": 100
}
]
}
]
Since the pipleline issue is by design, I am closing this. Please reopen is ConvertTo-Json -InputObject $array does not work.
In my case this approach adds "value": at the beggining and "Count": 1 at the end:
{
"value": [
{
"name": "Animals",
"age": "1",
"children": [
{
"name": "mimi",
"age": "1",
"lovely": true,
"height": 20
},
{
"name": "dog",
"age": "2",
"lovely": false,
"height": 100
}
]
}
],
"Count": 1
}
Does this support complex json files .
Referring to the Azure ARM templates which are in the json format .
Does it support that too ?
Most helpful comment
With the repro as is, it does look like it is by design - we enumerate objects written to the pipeline, so piping loses the fact that the object was an array. This is similar to the difference between:
I was going to suggest using:
But this doesn't work either, and I would consider this a bug.