0

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?

1
  • 1
    As an aside: PowerShell functions, cmdlets, scripts, and external programs must be invoked like shell commands - foo arg1 arg2 - not like C# methods - foo('arg1', 'arg2'). If you use , to separate arguments, you'll construct an array that a command sees as a single argument. To prevent accidental use of method syntax, use Set-StrictMode -Version 2 or higher, but note its other effects. See this answer for more information. Commented Dec 31, 2020 at 1:51

1 Answer 1

2

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
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.