I'm diving into PowerShell and trying to figure out how to work with JSON. I have a JSON file that looks something like this:
{
"1": {
"earned": 0
},
"19": {
"earned": 1,
"earned_time": 1000000000
},
"20": {
"earned": 1,
"earned_time": 1000000000
},
"16": {
"earned": 0
}
}
From this file, I want to extract all the entries where "earned" equals 1 or where "earned_time" exists. So, the desired output would be:
{
"19": {
"earned": 1,
"earned_time": 1000000000
},
"20": {
"earned": 1,
"earned_time": 1000000000
}
}
I've started with this line of code:
$inputFile = ".file.json"
$outputFile = ".new_file.json"
$coreJson = Get-Content -Path $inputFile -Raw | ConvertFrom-Json
But I'm unsure how to filter the objects based on my conditions. Any recommendations? Thanks!
5 Answers
You can use a script like this:
$inputFile = ".json.json"
$outputFile = ".new_file.json"
$coreJson = Get-Content -Path $inputFile -Raw | ConvertFrom-Json -AsHashtable
$outHash = [ordered]@{}
foreach ($key in $coreJson.Keys) {
if ($coreJson.$key.earned -or $coreJson.$key.earned_time) {
$outHash[$key] = $coreJson.$key
}
}
$outHash | ConvertTo-Json | Set-Content -Path $outputFile
Just make sure to add `ConvertTo-Json` at the end to get your desired output!
If you’re open to experimenting, I wrote a quick fix to clean the JSON format:
$text = '{
"1": {
"earned": 0
},
"19": {
"earned": 1,
"earned_time": 1000000000
},
"20": {
"earned": 1,
"earned_time": 1000000000
},
"16": {
"earned": 0
}
}'
$reformatted = $text.split("`r`n") | % { if ($_ -like "*: {") {"{ value: "+$_.replace(": {","")+"," } else {$_} }
$reformatted = $reformatted.split("`r`n") | % { if ($_ -eq "{") {"[" } else {$_} }
$reformatted = $reformatted.split("`r`n") | % { if ($_ -like " }") {"]" } else {$_} }
$final_list = $reformatted | convertfrom-json
$final_list | ? {$_.earned -eq 1}
That’s interesting! If you're in control of the JSON generation, simply avoid having an 'earned' property and instead check for 'earned_time' presence — it simplifies everything.
You can achieve filtering by treating the JSON like this:
$var1 = ('{
"1": {
"earned": 0
},
"19": {
"earned": 1,
"earned_time": 1000000000
},
"20": {
"earned": 1,
"earned_time": 1000000000
},
"16": {
"earned": 0
}
}' | ConvertFrom-Json)
($var1.PSObject.Properties | Where-Object Name -in ('19','20')).Value | ConvertTo-Json
This way, you can filter specific properties easily. You might find it more straightforward to manipulate them as PSCustomObjects.
Just a heads up, the structure of your JSON is not ideal. If you can, consider reformatting it. A cleaner version would be arrays with objects, like this:
[
{"value": 1, "earned": 0},
{"value": 19, "earned": 1, "earned_time": 1000000000},
{"value": 20, "earned": 1, "earned_time": 1000000000},
{"value": 16, "earned": 0}
]
Making that change will simplify your queries down the line!
Agreed! Thanks for the tip, I'll definitely look into restructuring it.
Consistent JSON structure is key. Make sure every object has the same properties to streamline filtering. For instance, if "earned_time" is relevant, it should appear for each object, potentially as null or 0 where not applicable.

Thanks for this, it's exactly what I needed! I was missing the ConvertTo-Json part. Cheers!