How to read a JSON file and rearrange the code - json

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.

Related

Iterate through a text file and add entries to the JSON using powershell

I have a text file with below data which is Dynamically generated, so the contents of the repo.txt keep changing
repo.txt -> Content as below
repo1
repo2
repo_3
And a JSON file
template.json -> Content as below
{
"name": "new-report-test-1",
"resources": {
"repositories": [
{
"name": "repoa"
},
{
"name": "repo_b"
}
]
},
"filters": {
"severities": [
"High"
]
}
}
now i want to read the repo list from the repo.txt file and update the template.json to below
{
"name": "new-report-test-1",
"resources": {
"repositories": [
{
"name": "repoa"
},
{
"name": "repo_b"
},
{
"name": "repo1"
},
{
"name": "repo2"
},
{
"name": "repo_3"
}
]
},
"filters": {
"severities": [
"High",
"Medium",
"Critical"
]
}
}
I have this bash script that does the job thiugh I'm unsure how to translate it to PoweShell. Any inputs would be highly appreciated
cat ./tmpgen_reponames.txt | while read repoEntry do echo " Repository: $repoEntry" cat <<< $(jq --arg REPOID "$repoEntry" '[ .[] , {"name":$REPOID} ]' tmpgen_repoarray.json) > tmpgen_repoarray.json done
You can accomplish this in PowerShell using ConvertFrom-Json to convert your Json into objects then following an object-oriented approach adding new custom objects to the .resources.repositories property and adding the new values Medium and Critical to the .filters.severities property of your Json, lastly, converting it back to a Json string with ConvertTo-Json:
$json = Get-Content path\to\template.json -Raw | ConvertFrom-Json
$json.resources.repositories = #(
$json.resources.repositories
(Get-Content path\to\repo.txt).Trim() | ForEach-Object {
[pscustomobject]#{ Name = $_ }
}
)
$json.filters.severities = #(
$json.filters.severities
'Medium'
'Critical'
)
$json | ConvertTo-Json -Depth 99 | Set-Content path\to\newJson.Json

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

How to add a value and key into existing JSON file over powershell?

I would like to add an additional key with value into my existing JSON file. Unfortunately I'm not able. Here an short overview:
My JSON-File before powershell script is run:
[
{
"id": "1",
"description": [
{
"country": "Brazil"
},
{
"country": "Mexico"
}
]
},
{
"id": "2",
"description": [
{
"country": "Argentina"
}
]
}
]
My wish, how the JSON-File should look like, after my powershell script is run:
[
{
"id": "1",
"description": [
{
"country": "Brazil",
"city": "Rio de Janeiro"
},
{
"country": "Mexico",
"city": "Mexico City"
}
]
},
{
"id": "2",
"description": [
{
"country": "Argentina",
"city": "Buenos Aires"
}
]
}
]
My powershell script:
function GetCity($country) {
$x = "not available"
If ( $country -eq "Brazil" ) { $x = "Rio de Janeiro" }
If ( $country -eq "Mexico" ) { $x = "Mexico City" }
If ( $country -eq "Argentina" ) { $x = "Buenos Aires" }
return $x
}
# Source the JSON content
$jsonFile = 'C:\Temp\test.json'
$jsonContent = Get-Content -Path $jsonFile
# Convert JSON to PSObjects
$jsonAsPsObjects = $jsonContent | ConvertFrom-Json
foreach ($info in $jsonAsPsObjects) {
$result = GetCity($info.description.country)
jsonContent | Add-Member -Type NoteProperty -Name "City" -Value $result
}
# Save JSON back to file
$json | ConvertTo-Json | Set-Content $jsonFile
Error:
jsonContent : The term 'jsonContent' is not recognized as the name of
a cmdlet, function, script file, or operable program. Check the
spelling of the name, or if a path was included, verify that the path
is correct and try again.
How can I solve this issue?
There at two problems:
jsonContent should be $jsonContent in statement jsonContent | Add-Member ...
You're neglecting to loop over the array elements of the description property, to each of which a city property is to be added.
I suggest streamlining your code as follows:
function Get-City {
param([string] $country)
# Use a `switch` statement:
switch ($country) {
'Brazil' { return 'Rio de Janeiro' }
'Mexico' { return 'Mexico City' }
'Argentina' { return 'Buenos Aires' }
default { return 'not available' }
}
}
$jsonFile = 'C:\Temp\test.json'
(Get-Content -Raw $jsonFile | ConvertFrom-Json) | ForEach-Object {
# Add a 'city' property to each object in the 'description' property.
$_.description.ForEach({
Add-Member -InputObject $_ city (Get-City $_.country)
})
$_ # output the modified object
} | ConvertTo-Json -Depth 3 # | Set-Content $jsonFile

I am facing issue is modifying a value in json file using powershell

I have a json file with below contents
{
"createOrReplace": {
"object": {
"database": "DB_NAME"
},
"database": {
"name": "DB_NAME",
"compatibilityLevel": 1400,
"model": {
"culture": "en-IN",
"dataSources": [{
"name": "somename",
"connectionString": "somevalue",
"impersonationMode": "impersonateServiceAccount",
"annotations": [{
"name": "ConnectionEditUISource",
"value": "SqlServer"
}]
}]
}
}
}
}
and I am using following a PowerShell script to update the name under dataSources.
$JsonFilePath = "path-to-json-file"
$JsonData = Get-Content $JsonFilePath -raw | ConvertFrom-Json
$JsonData.createOrReplace.database.model.dataSources[0].name = "ssasservername"
$JsonData | ConvertTo-Json | set-content $JsonFilePath
Can anyone help me to set a value of an object inside the array?
$JsonData.createOrReplace.database.model.dataSources[0].name = "ssasservername"
Also note: Unexpected ConvertTo-Json results? Answer: it has a default -Depth of 2:
$JsonData | ConvertTo-Json -Depth 9 | set-content $JsonFilePath