Read JSON and Iterate in Powershell - json

I have a JSON file where I have maintained few settings. Below is my JSON File
{
"1":{
"foundation_name":"Pre-Prod1",
"api_url": "https://sys1.com"
},
"2":{
"foundation_name":"Pre-Prod2",
"api_url": "https://sys-2.com"
},
"3":{
"foundation_name":"Prod1",
"api_url": "https://sys5.com"
}
}
And I am trying to read this JSON and PRINT it in my screen by Iterating it. Below is my Powershell script
Function FoundationSettings {
Write-Host 'Reading from File'
$foundations = Get-Content ".\foundations.json" -Raw | ConvertFrom-Json
Write-Host $foundations
return $foundations
}
Function DisplayFoundations {
$foundations = FoundationSettings
foreach ($foundation in $foundations) {
Write-Host 'here ..'
Write-Host $foundation.foundation_name
}
}
But it just prints this way
Reading from File
#{1=; 2=; 3=}
here ..
How to solve it ? I need to parse the JSON and at my demand i would have get the api_url data and foundation_name

If that format is unchangeable, you can use:
$obj = #'
{
"1":{
"foundation_name":"Pre-Prod1",
"api_url": "https://sys1.com"
},
"2":{
"foundation_name":"Pre-Prod2",
"api_url": "https://sys-2.com"
},
"3":{
"foundation_name":"Prod1",
"api_url": "https://sys5.com"
}
}
'# | ConvertFrom-Json
$listOfObjects = ($obj | Get-Member -MemberType NoteProperty).Name | % { $obj.$_ }
If you can change it, use JSON array where array is more appropriate:
$listOfObjects | ConvertTo-Json
Which gives:
[
{
"foundation_name": "Pre-Prod1",
"api_url": "https://sys1.com"
},
{
"foundation_name": "Pre-Prod2",
"api_url": "https://sys-2.com"
},
{
"foundation_name": "Prod1",
"api_url": "https://sys5.com"
}
]

Access the value of the underlying properties:
Function DisplayFoundations {
$foundations = FoundationSettings
foreach ($foundation in $foundations.psobject.Properties.Value) {
Write-Host 'here ..'
Write-Host $foundation.foundation_name
}
}

Related

PowerShell ConvertTo-Json object output with leading unwanted numbers

Below function is giving me required result except the numbers (0,1,2,0) populating before JSON object beginning. Can someone help me to get rid of those numbers.
$V1='11' $V2='1881' $V3='111','222','333'
$body=CreateJsonBody $V1 $V2 $V3
function CreateJsonBody{
param($objectId,$AttributeId,$AttributeValues)
$jsonBase=#{"objectId"= $objectId;}
$vlist = New-Object System.Collections.ArrayList
$alist = New-Object System.Collections.ArrayList
foreach ($Val in $AttributeValues) {
$vlist.Add(#{"value"= $Val;})
}
$alist.Add(#{"AttributeId"= $AttributeId;"AttributeValues"=$vlist;})
$jsonBase.Add("attributes",$alist)
return $jsonBase | ConvertTo-Json -Depth 10
}
Output:
PS C:\WINDOWS\system32> $body
0
1
2
0
{
"objectId": "105",
"attributes": [
{
"AttributeId": "1887",
"AttributeValues": [
{
"value": "111"
},
{
"value": "222"
},
{
"value": "333"
}
]
}
]
}

Powershell - Remove from Json

I have the following Json file:
{
"Id":1,
"Name":"john",
"Addresses":[
{
"Id":1,
"Street":"1st Street",
"City":"Riyadh"
},
{
"Id":2,
"Street":"2nd Street",
"City":"Dammam"
}
]
}
I want to remove the second address in the array using powershell.
I tried the following:
$filePath = 'C:\temp\Settings.json'
$settings = $filePath | ConvertFrom-Json
foreach($item in $settings.Addresses)
{
if($item.Id -eq 2)
{
$settings.Addresses.Remove($item)
}
}
Any ideas?
The following commented code snippet could help:
$filePath = 'C:\temp\Settings.json'
$settings = Get-Content -Path $filePath | ConvertFrom-Json
# $settings.Addresses # is an array of fixed size
# $settings.Addresses.IsFixedSize # returns True
# $settings.Addresses.Remove($item) # isn't possible; hence, let's build new array:
$NewAddresses = [System.Collections.ArrayList]::new()
foreach($item in $settings.Addresses)
{
if ($item.Id -ne 2)
{
[void]$NewAddresses.Add( $item )
}
}
# and replace old one:
$settings.Addresses = $NewAddresses
$settings | ConvertTo-Json ### | Out-File -FilePath $filePath -Force -Encoding utf8
Output: .\SO\66855002.ps1
{
"Id": 1,
"Name": "john",
"Addresses": [
{
"Id": 1,
"Street": "1st Street",
"City": "Riyadh"
}
]
}

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

How to increment a key value pair in JSON file

I have a JSON file that I would need a certain value to be incremented. Here is the JSON file structure I have.
{
"Body": {
"Content": {
},
"Lines": [{
"LineNumber": "1",
"DateOfService": "10/20/2017"
},
{
"LineNumber": "1",
"DateOfService": "10/20/2017"
},
{
"LineNumber": "1",
"DateOfService": "10/20/2017"
}]
}
}
I want the "LineNumber" values to be set from 1 and incremented by 1 subsequently. I have close to a 1000 lines.
Thanks for your assistance.
$InputFile = "path\name.json.txt"
$OutPutFile = "path\name.new.json"
$objJsonFile = Get-Content -Raw -Path $InputFile | ConvertFrom-Json
$intLine = 1
foreach ($itmLine in $objJsonFile.Claim.Lines)
{
$itmLine.LineNumber = [string]$intLine++
}
$objJsonFile | ConvertTo-Json -Depth 3 | Out-File $OutPutFile
You could try to do so using the following code.
$fileContent = Get-Content PATH\TO\FILE.json;
$json = $fileContent | ConvertFrom-Json;
$counter = 1;
ForEach($line in $json.Body.Lines) {
$line.LineNumber = $counter;
$counter++;
}
# write json back to file!?

Get values from JSON with Powershell

Very beginner question. I'm trying to get certain values from JSON with Powershell.. Specifically, I want to list the Services: TEST00000 and FAKE only.
When I run the script below, I get this:
TEST00000 FAKE
--------- ----
#{Enabled=True; Processed=2; Sent=3; Failed=4; Downloaded=5} #{Enabled=True}
How can I get a list of only the services?
More importantly, how do I list only the services which has the key/value Enabled=True present inside of them?
Here is the code:
$JSON = '{
"Envs": {
"DEV": {
"Services": {
"TEST00000": {
"Enabled": true,
"Processed": 2,
"Sent": 3,
"Failed": 4,
"Downloaded": 5
},
"FAKE": {
"Enabled": true
}
}
}
},
"Component": {
"Digger": {
"Envs": {
"DEV": {
"DownloadE": 4
}
}
}
}
}'
$jsonobj = ConvertFrom-Json -inputObject $JSON
$jsonobj.Envs.DEV.Services
To get the name of each Services property. You can use Get-Member like user2734259 did or you can use the psobject property which stores useful information about an object.
$ServiceNames = $jsonobj.Envs.DEV.Services.psobject.properties.name
Once you have the names you can loop over them and filter on the sub-property Enabled
$jsonobj.Envs.DEV.Services.psobject.properties.name | ForEach-Object {
$_ | Where-Object {$jsonobj.Envs.DEV.Services.$_.Enabled -eq $True}
}
This should allow you to get the names dynamically, regardless of the service name in your JSON:
$JSON = '{
"Envs": {
"DEV": {
"Services": {
"TEST00000": {
"Enabled": true,
"Processed": 2,
"Sent": 3,
"Failed": 4,
"Downloaded": 5
},
"FAKE": {
"Enabled": true
}
}
}
},
"Component": {
"Digger": {
"Envs": {
"DEV": {
"DownloadE": 4
}
}
}
}
}'
$jsonobj = ConvertFrom-Json -inputObject $JSON
$enabledServices = $NULL
$disabledServices = $NULL
# Since the service names are arbitrary
# create an object that contains only
# objects whose MemberType is NoteProperty
$strServiceNames = #($($jsonobj.Envs.DEV.Services | Get-Member | Where { $_.MemberType -eq "NoteProperty" } | Select Name).Name)
$pscoServiceNames = [PSCustomObject]#{Names=$strServiceNames}
foreach($serviceName in $pscoserviceNames.Names)
{
# dynamically access the service name
# from $jsonobj.Envs.DEV.Services
$serviceStatus = $jsonobj.Envs.DEV.Services.$serviceName.Enabled
# parse results based on value of .Enabled
if($serviceStatus.ToString() -eq "True")
{
$enabledServices = [Array]$enabledServices + [PSCustomObject]#{Name = $serviceName;Enabled = $serviceStatus}
}
else
{
$disabledServices = [Array]$disabledServices + [PSCustomObject]#{Name = $serviceName;Enabled = $serviceStatus}
}
}
# Show the results
Write-Output "`nEnabled Services`n"
$enabledServices | Format-List
Write-Output "`nDisabled Services`n"
$disabledServices | Format-List
If anything is unclear let me know and I can explain in more detail
Hope this helps you out.
Happy 'shelling!