Extract Value from JSON Using PowerShell based on condition - json

I have the captured the JSON response in variable $releaseDefinitions. With this i want to extract the "ID" as "4598" when i pass the "name" as "STAGE1-PG-DB" under the "environments" tag using the powershell.
Any help on this is much appreciated.
{
"id": 516,
"environments": [
{
"id": 4598,
"releaseId": 516,
"name": "STAGE1-PG-DB",
"status": "notStarted",
},
{
"id": 4599,
"releaseId": 516,
"name": "STAGE2-PG-DB",
"status": "notStarted",
},
{
"id": 4600,
"releaseId": 516,
"name": "STAGE3-PG-DB",
"status": "notStarted",
}
]
}

I believe you are asking to get the JSON array object where the name is "STAGE1-PG-DB".
Based on the info you've provided, you would do something like this (see my in-line comments)
$releaseDefinitions = Get-Content -Path $inputFileName -Raw | ConvertFrom-Json
# use dot-notation to get the entire Environments array
# pipe the array through using the pipe character
# filter through the array where the key (Name) is equal to your value (STAGE1-PG-DB)
$releaseDefinitions.environments | Where-Object {$_.name -eq "STAGE1-PG-DB"}

Related

How to read specific Key from JSON file with Powershell

I'm trying to read a Json file with some passwords but them are stored into Key-Value pattern as below:
{
"id": "a8cc4184-3844-4605-8e35-ea479ae1094e",
"name": "Test Credentials and Secrets",
"values": [
{
"key": "apassword",
"value": "mypassword",
"enabled": true
},
{
"key": "tpassword",
"value": "my other password",
"enabled": true
},
],
"exported_using": "Postman/7.34.0"
}
How can I get any specific value with PowerShell? tpassword value for instance.
I would recommend using ConvertFrom-Json to turn it into an Object so you can then access the properties easily with PowerShell.
I saved the json above to C:\temp\json.json and then the following got me the tpassword value:
$json = Get-Content C:\temp\json.json | ConvertFrom-Json
$json.values | Where-Object key -eq 'tpassword' | Select-Object Value

Only remove/Exclude an attribute from json if it exists

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 array address, because the call is an effective no-op for those objects that already lack a streets 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:
Get-Content -Raw Test.json | ConvertFrom-Json |
ForEach-Object {
[array] $_.address = $_.address | select * -exclude streets; $_
}
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:
Get-Content -Raw Test.json | ConvertFrom-Json |
ForEach-Object {
$_.address.ForEach({ $_.psobject.Properties.Remove('streets') }); $_
}
With your sample JSON input, both commands output the following:
Customer Nationality address
-------- ----------- -------
{#{id=123}} {#{name=US; id=456}} {#{$type=Home; name=Houston}, #{$type=Home5; name=Houston5}, #{$type=Office; name=Hawai}}
Note how the objects in the address column no longer have a streets property.
Caveat: Note that ConvertTo-Json limits the serialization depth to 2 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.

How to replace string in json file which have a variable using powershell

I have a json as below. Want to replace '$content' in the json with 'test/abc'
{
"$version": "0.0.1",
"description": "",
"content": {
"url": "$content",
"tag": {
"version": "0.0.1",
},
"buildOptions": []
},
"env": "qa"}
I tried by converting it to JSON object but since there is a variable in that in gives me "ConvertFrom-Json : Invalid JSON primitive" error.
$JsonData = Get-Content module.json -raw | ConvertFrom-Json
How can I replace $content with test/abc?
you can escape the $ - either manually or with the [regex]::Escape() method. [grin]
if $InStuff contains your sample data in a here-string, then this will do the replacement ...
$InStuff -replace [regex]::Escape('$content'), 'test/abc'
hope that helps,
lee

ConvertFrom-JSON strips array from object

I'm loading a text file containing some Json to edit a property. However, after modifying the content and writing it to file, the Json becomes invalid.I
I use the following PowerShell to modify the file:
$manifest = Get-Content $PathToManifest -Raw | ConvertFrom-Json
#modify Json
Set-Content -Path $PathToManifest -Value ( $manifest | ConvertTo-Json)
The following snippet from my Json file gets corrupted:
"contributions": [
{
"id": "sample-data-widget",
"type": "ms.vss-dashboards-web.widget",
"targets": ["ms.vss-dashboards-web.widget-catalog"],
"properties": "#{name=Sample Data; description=Create sample data in a VSTS project.; previewImageUrl=img/logo.png; uri=index.html; supportedSizes=System.Object[]; supportedScopes=System.Object[]}"
}]
After loading the Json and writing it back to file the array syntax around targets is gone:
"contributions": [
{
"id": "sample-data-widget",
"type": "ms.vss-dashboards-web.widget",
"targets": "ms.vss-dashboards-web.widget-catalog",
"properties": "#{name=Sample Data; description=Create sample data in a VSTS project.; previewImageUrl=img/logo.png; uri=index.html; supportedSizes=System.Object[]; supportedScopes=System.Object[]}"
}]
Why is this happening? Is there a way to make sure the syntax doesn't change?
ConvertTo-Json has Depth parameter that controls how many levels of contained objects are included in the JSON representation. The default value is 2. ConvertTo-Json will call .ToString() on anything nested deeper than specified Depth.
So all you need is to specify sufficiently large number for Depth argument or just ([int]::MaxValue).
Set-Content -Path $PathToManifest -Value ( $manifest | ConvertTo-Json -Depth ([int]::MaxValue))
Examples of nesting and ConvertTo-Json behavior:
$NestedArray = #(1,#(2,#(3,#(4))))
Default:
$NestedArray | ConvertTo-Json
[
1,
{
"value": [
2,
[
3,
"4"
]
],
"Count": 2
}
]
No nesting at all:
$NestedArray | ConvertTo-Json -Depth 1
[
1,
{
"value": [
2,
"3 System.Object[]"
],
"Count": 2
}
]
Desired result:
$NestedArray | ConvertTo-Json -Depth 3
[
1,
{
"value": [
2,
[
3,
[
4
]
]
],
"Count": 2
}
]

Powershell convertfrom-json | convertto-csv

I have a JSON data structured as following (there may be some mistakes here, the data I'm using is fine):
[{
"id": 12345,
"itemName": "some string",
"sellerId": 123,
"seller": "",
"categoryId": ,
"categoryPath": [
{
//more data
},
{
//more data
}
]},
{"id": 12346,
"itemName": "some other string",
"sellerId": 234,
"seller": "",
"categoryId": ,
"categoryPath": [
{
//more data
},
{
//more data
}
]
}]
I would like to convert it to csv so that the selected property names become csv headers and their value (depth 1 only) become data.
e.g
id,itemName,sellerId
12345,"some string",123
12346,"some other string",234
I've tried using hundreds of variations of
cat file.json | convertfrom-json | convertto-csv
but none have worked. All I get is csv data with objects names/types and I can't figure out how to make it use only selected properties of each object from json data.
In short you need to do something like this:
(Get-Content file.json -Raw | ConvertFrom-Json) | Select id,itemName,sellerId | Convertto-CSV -NoTypeInformation
The first problem was that Get-Content was passing individual lines to ConvertFrom-Json which is not what it wants. Using the -Raw switch passes it in its entirety.
The (Get-Content file.json -Raw | ConvertFrom-Json) needs to be in parentheses as that allows us to continue with the pipe. The properties are not accessible without doing this. It looks like it is trying to pass the entire object instead of its individual parts down the pipe.
-NoTypeInformation removes lines like this
#TYPE Selected.System.Management.Automation.PSCustomObject