I have following JSON and I would like to remove streets from the JSON object if only it exists under Address which is an array. I am trying to do this in powershell. I can get my script working and remove the streets but I only want to run the exclude line of command if the address has the streets property. Is that possible?
{
"Customer": [{
"id": "123"
}],
"Nationality": [{
"name": "US",
"id": "456"
}],
"address": [{
"$type": "Home",
"name": "Houston",
"streets": [{
"name": "Union",
"postalCode": "10"
}]
},
{
"$type": "Home5",
"name": "Houston5"
},
{
"$type": "Office",
"name": "Hawai",
"streets": [{
"name": "Rock",
"postalCode": "11"
}]
}
]
}
Powershell script
$FileContent = Get-Content -Path "Test.json" -Raw | ConvertFrom-Json
#Only want to run for address objects that contains streets
$FileContent.address = $FileContent.address | Select-Object * -ExcludeProperty streets #Only would like to run if object address has streets property
$FileContent | ConvertTo-Json
Note:
This answer performs the same operation as in the question, only more succinctly, in a single pipeline.
It is benign to run
Select-Object * -ExcludeProperty streets
against all objects in arrayaddress
, because the call is an effective no-op for those objects that already lack astreets
property (though a copy of such objects is created too).You need an assignment to modify your objects in-place before outputting them, which requires a
ForEach-Object
call:Note how each object parsed from the JSON input is first modified via the assignment (
$_.address = ...
), and then passed out ($_
).A more efficient, but a little more obscure variant:
With your sample JSON input, both commands output the following:
Note how the objects in the
address
column no longer have astreets
property.Caveat: Note that
ConvertTo-Json
limits the serialization depth to2
by default, which is sufficient in this case, but in other cases you may have to pass a-Depth
argument to prevent data loss - see this post.