I have empty settings.json file
{
}
I want to add section with powershell and to look like this:
{
"ParentObj": {
"ChildProp": "test"
}
}
I use this sample of code to achieve this :
$SettingFile = Get-Content 'c:zsetting.json' -raw -Encoding UTF8 | ConvertFrom-Json
if (-not $SettingFile.PSObject.Properties['ParentObj']) {
$SettingFile | Add-Member -MemberType NoteProperty -Name ParentObj -Value @{}
}
if (-not $SettingFile.ParentObj.PSObject.Properties['ChildProp']) {
Write-Host 'section 1'
$SettingFile.ParentObj | Add-Member -MemberType NoteProperty -Name 'ChildProp' -Value 'test'
} else {
Write-Host 'section 2'
$SettingFile.ParentObj.ChildProp = 'test2'
}
$SettingFile | ConvertTo-Json -Depth 10 | set-content 'c:zsetting.json' -Encoding UTF8
On the first run of the script I always have empty ParentObj without ChildProp although it says it enter in section 1 of if to create child prop
{
"ParentObj": {
}
}
i have workaround but i want to understand why on the first run ChildProp is not created, what I am misunderstanding about PowerShell behaviour ?
2
Answers
Replace:
-Value @{}
with:
-Value ([pscustomobject]@{})
@{}
creates an empty hashtable rather than a[pscustomobject]
, and you want the latter.By using a hashtable, the subsequent
Add-Member
call decorated the empty hashtable stored in.ParentObject
with aChildProp
ETSNoteProperty
property, which was in effect ignored byConvertTo-Json
– only the empty hashtable itself was serialized and – given that serializing a hashtable to JSON means serializing its entries and there none – you ended up with an emptyParentObj
property in the output JSON.By contrast, a
[pscustomobject]
instance is entirely composed ofNoteType
properties that are considered first-class property citizens and therefore all serialize to JSON.Your issue is when you do
-Value @{}
instead of-Value ([psobject]::new())
, in simple terms:If you’re running PowerShell 7 you might find it easier if you deserialize your Json
-AsHashtable
, you could approach your code like this: