Select a node from a JSON file that matches a property value - json

I am having a json object stored in a variable. From the json object, I want to fetch the node which matches a value. For example - an item having machineId 12.
My json looks like
{
"items": [
{
"id": "asdasd",
"machineId": "12",
"placementGroup": "",
"region": "158",
"staticIp": "",
"staticIpAction": "",
"subnetIDs": [
]
},
{
"id": "asdasd",
"machineId": "43",
"placementGroup": "",
"region": "158",
"staticIp": "",
"staticIpAction": "",
"subnetIDs": [
]
}
]
}

Load the json using the Get-Content cmdlet and convert it to json using the ConvertFrom-Json cmdlet. Select the items node and filter it by the desired machineId using the Where-Object cmdlet:
Get-Content 'yourPathToYour.json' |
ConvertFrom-Json |
Select-Object -ExpandProperty items |
Where-Object machineId -eq 12
Output:
id : asdasd
machineId : 12
placementGroup :
region : 158
staticIp :
staticIpAction :
subnetIDs : {}

Related

Sort JSON objects by value of the key (Index) in PowerShell

I'm trying to sort the following JSON objects by the value of the "Index" key.
JSON = {
"PIPoint": {
"Label": "\"PIPoint\"",
"Visible": "True",
"Index": "2"
},
"Description": {
"Label": "\"Description\"",
"Visible": "True",
"Index": "3"
},
"Analysis": {
"Label": "\"Analysis\"",
"Visible": "True",
"Index": "4"
},
"PIPointExist": {
"Label": "\"PIPointExist\"",
"Visible": "True",
"Index": "5"
},
"Custom Location": {
"Label": "\"Custom Location\"",
"Visible": "True",
"Index": "1"
}
}
I've try the following code but it did not work
$json = Get-Content 'C:\column.json' | ConvertFrom-Json
$json = $json | Sort-Object -Property {$_.Index}
$json | ConvertTo-Json | Out-File 'C:\\column_sorted.json'
One way to do this would be to sort the properties and use Select-Object to reorder the output:
# Return objects based on JSON strings
$jsonObjs = Get-Content 'C:\column.json' | ConvertFrom-Json
# Sorted properties list
$Properties = ($jsonObjs.psobject.properties | Sort-Object {[int]$_.Value.Index}).Name
# Create new JSON strings with new order
$jsonObjs | Select-Object $Properties | ConvertTo-Json
$jsonĀ¹ is a single object (with just 5 properties).
So you need to sort the properties:
$Data = Get-Content 'C:\column.json' | ConvertFrom-Json
$Properties = [ordered]#{}
$Data.PSObject.Properties |Sort-Object { $_.Value.Index } |ForEach-Object { $Properties[$_.Name] = $_.Value }
[pscustomobject]$Properties | ConvertTo-Json
I would call it $Json as it is no longer a Json string but an object

Parse json values into a single row

{
"value": [{
"ExternalKey": "12345",
"PortfolioId": "ABC",
"InceptionDate": null,
"TerminationDate": null,
"Version": 2,
"SourceRef": "ABC",
"MasterSeries": [{
"Points": [{
"Date": "1900-01-01T00:00:00+00:00",
"Name": "XYZ Name",
"Type": "IP",
"Status": "Active",
"Version": 1
}],
"ExternalKey": "12345",
"Version": 1,
"IsDeleted": false,
"SourceRef": "ABC"
}]
}]
}
I tried to loop through each level and manually selecting the keys
ForEach($d in $json.value) { $row=$d.column1+","+ $d.column2 ..
$rootProps = $d| Get-Member | Where-Object { $_.MemberType -match "Property"}
$rootProps | ForEach-Object {
if($_.Name -eq "MasterSeries") {
$d | select -Expand MasterSeries | select-object * -ExcludeProperty Points | ForEach { $row = $_.column1 + "," $_.column2 ..
}
}
and so on..... but when I export it to Out-File "Export.csv" and try importing it gives me a UTF error. Is there a better way to achieve?
If this helps any, here's the typical way to loop through json properties in powershell 5 using the hidden psobject.properties. You might search for "flatten json".
$a = get-content file.json | convertfrom-json
$a.value[0].psobject.properties | select name,value
Name Value
---- -----
ExternalKey 12345
PortfolioId ABC
InceptionDate
TerminationDate
Version 2
SourceRef ABC
MasterSeries
For this you will need to create a recursive function.
To make things easier, I recommend you to use the ConvertFrom-Json -AsHashTable parameter which will return [HashTable] objects rather than [PSCustomObject] Objects
Function Get-Values($Object) {
if ($Object -is [String]) { $Object } # A string is also Enumerable
elseif ($Object -is [Collections.IDictionary]) { $Object.get_Values() | ForEach-Object { Get-Values $_ } }
elseif ($Object -is [Collections.IEnumerable]) { $Object.GetEnumerator() | ForEach-Object { Get-Values $_ } }
else { $Object }
}
$Object = ConvertFrom-Json -AsHashTable '{
"value": [
{
"ExternalKey": "12345",
"PortfolioId": "ABC",
"InceptionDate": null,
"TerminationDate": null,
"Version": 2,
"SourceRef": "ABC",
"MasterSeries": [
{
"Points": [
{
"Date": "1900-01-01T01:00:00+01:00",
"Name": "XYZ Name",
"Type": "IP",
"Status": "Active",
"Version": 1
}
],
"ExternalKey": "12345",
"Version": 1,
"IsDeleted": false,
"SourceRef": "ABC"
}
]
}
]
}'
Get-Values $Object
12345
False
1
IP
Monday, January 1, 1900 1:00:00 AM
XYZ Name
Active
ABC
1
12345
2
ABC
ABC

Need to search a text file for a string and capture a second string located after the first

I'm working with an API call and I need to parse the JSON returned by the API in PowerShell. I'm searching for a particular name and then I need to capture a another item that follows it.
$json = #"
{
"Test": [
{
"association": "(None)",
"description": "",
"displayName": "BusIntel48.png",
"galleryImage": "[PlugIn]Images;Trebuchet.PlugIn.Images.Images.Common.BusIntelligence.BusIntel48.png",
"id": "944f73cc5c1a812eaa2ade43bd9ca0c9a40f963c56",
"links": [],
"localizedScopeName": "Built in",
"name": "BusIntel48.png",
"parentFolder": "ImagesCommonBusIntelligence",
"parentIsScopeFolder": false,
"scope": "FromResource",
"scopeOwner": "",
"standInKey": "DefType:ImageDef#Scope:FromResource#Id:944f73cc5c1a812eaa2ade43bd9ca0c9a40f963c56"
},
{
"association": "(None)",
"description": "",
"displayName": "BusProcActOnEvent16.png",
"galleryImage": "[PlugIn]Images;Trebuchet.PlugIn.Images.Images.Common.BusIntelligence.BusProcActOnEvent16.png",
"id": "944f73cc5cb33339be6db84987baef3f7190c931cf",
"links": [],
"localizedScopeName": "Built in",
"name": "BusProcActOnEvent16.png",
"parentFolder": "ImagesCommonBusIntelligence",
"parentIsScopeFolder": false,
"scope": "FromResource",
"scopeOwner": "",
"standInKey": "DefType:ImageDef#Scope:FromResource#Id:944f73cc5cb33339be6db84987baef3f7190c931cf"
}
]
}
"#
$x = $json | ConvertFrom-Json
$name = $x.Test | where { $_.name -eq "BusIntel48.png" }
I need to search for the name of the image file (ex. "name": "BusIntel48.png") and then capture the string after "standInKey: (ex. DefType:ImageDef#Scope:FromResource#Id:944f73cc5c1a812eaa2ade43bd9ca0c9a40f963c56).
Just need a change in last line.
You can also select one property by using :
$name = $x.Test | where { $_.name -eq "BusIntel48.png" } | Select-Object -Property "standInKey"

Get the node value from json in powershell

I have json body in powershell variable and want to get value from it.
Json Body :
"value": [
{
"id": 1,
"scope": "3e93f9e6-f427-48e1-b37b-994d196e1121",
"name": "Default",
"isHosted": false,
"poolType": "automation",
"size": 3
},
{
"id": 2,
"scope": "3e93f9e6-f427-48e1-b37b-994d196e1121",
"name": "Hosted",
"isHosted": true,
"poolType": "automation",
"size": 10
},
{
"id": 4,
"scope": "3e93f9e6-f427-48e1-b37b-994d196e1121",
"name": "Hosted VS2017",
"isHosted": true,
"poolType": "automation",
"size": 10
}]
I want to get the id value where name=Hosted VS2017 i.e 4
powershell :
Write-Host "json body:" $projects
$id = $projects.value | where { $_.name -eq "Hosted VS2017" }
Write-Host "id :" $id
You need to convert your JSON into a powershell object before you can work with it:
$projects = $projects | ConvertFrom-Json
Then you can access its members:
#requires -Version 3
$projects.value | ? name -eq 'Hosted VS2017'

How to read a JSON file and rearrange the code

I want to read my JSON file and write the same file with a rearranged code.
My JSON file give me something like that:
{
"one": [
{
"name": { "displayName": "Alex" },
"two": [
{
"date": "20072008",
"data": {
"id": "524556",
"fullname": "Alexandre Gagne",
"name": "Alexandre",
"lastName": "Gagne"
}
}
]
}
]
}
But I want something like this
{
"id": "524556",
"fullname": "Alexandre Gagne",
"name": "Alexandre",
"lastName": "Gagne"
}
Here's the code I use:
$jsonfile118 = 'C:/Users/Web_Q/Desktop/json/8472382-2017-2018.json'
$json118 = Get-Content $jsonfile118 | Out-String | ConvertFrom-Json
$json118.stats.splits
$json118 | Add-Member -Type NoteProperty -Name "id" -Value 524556
$json118 | ConvertTo-Json -Depth 10 | Set-Content $jsonfile118
I also use another piece of code that give me what I want but only in the terminal, when I use Set-Content the output looks like this:
"{ \'id'\ 536453 }"
Here's the code:
(New-Object PSObject |
Add-Member -PassThru NoteProperty id $json118.stats.splits.getId
) | ConvertTo-Json
What you need is,
Convert the Json to Object
Select the required member
Convert back to json
$Data = $JsonString | ConvertFrom-Json
$Data.One.Two.Data | ConvertTo-Json
Using this Flatten-Object cmdlet:
#'
{
"one": [
{
"name": { "displayName": "Alex" },
"two": [
{
"date": "20072008",
"data": {
"id": "524556",
"fullname": "Alexandre Gagne",
"name": "Alexandre",
"lastName": "Gagne"
}
}
]
}
]
}
'# | ConvertFrom-Json | Flatten-Object -Depth 9 -Base "" | ConvertTo-Json
Result:
{
"one.name.displayName": "Alex",
"one.two.date": "20072008",
"one.two.data.id": "524556",
"one.two.data.fullname": "Alexandre Gagne",
"one.two.data.name": "Alexandre",
"one.two.data.lastName": "Gagne"
}
It is not exactly what you defined as "Something like this" because it uses the parent names in the property names. This is to make sure that the names are always unique as it is technical possible to have the same child names under different parents.