0

How can I replace a value in a JSON file with another value taken from a config file (JSON)? This is the code for the JSON files:

Config.json

{
    "ABlob_AAD_Snapshot": [
    {
      "name": "properties.availability.frequency",
      "value": "$Frequency$"
    }]       
}

ABlob_AAD_Snapshot.json

{
  "name": "AzureBlobStore",
  "properties": {
                 "type": "AzureStorage",
                 "availability": {
                                 "frequency": "Value from Config.json file"
                                 }
                 }
}

What I'm trying to do is the following:

  1. Go through the Config.json file and store the values for "name" and "value" segments in variables. The "name" segment value is a path in ABlob_AAD_Snapshot.json file.
  2. Follow the path in the ABlob_AAD_Snapshot.json file and replace the segment "frequency" with the value of segment "value" ($frequency$)

After this process, the ABlob_AAD_Snapshot.json should look like this:

{
  "name": "AzureBlobStore",
  "properties": {
                 "type": "AzureStorage",
                 "availability": {
                                 "frequency": "$frequency$"
                                 }
                 }
}

The problem here is that my original config.json file has more than one array (which represents file names) so I will parse more than one file and the value for "name" segment will not always be the same I mean, in this case, the value (or path) is properties.availability.frequency but it could be properties.activities.scheduler.interval or properties.activities.typeProperties.extendedProperties.WebAppClientID.

So as you can see the name and the quantity of "nodes" could change.

This is my PowerShell script:

    $ScriptPath = split-path -parent $MyInvocation.MyCommand.Definition 

#path to config file
$ConfigFile = "$ScriptPath\ParameterConfigOriginal.json"

#Convert the json file to PSObject
$json = Get-Content $ConfigFile | Out-String | ConvertFrom-Json


#Get all the arrays (files) in Conifg.json
$files = $json | Get-Member -MemberType Properties | Select-Object -ExpandProperty Name

#Go through all the arrays (files)
Foreach($file in $files)
{
   if( $file -eq '$schema') {continue}

    #store the path of the file to be modified
    $FileName = $file + ".json"
    $FilePath = "$ScriptPath\LinkedServices\" + $FileName"

   #Go through all the elements of the arrray
   Foreach($item in $json.$file)
   {
     #Store the path 
     $name = $item.name


    #Store the value
    $value = $item.value

    #Convert the file to be modified to PSObject
    $file = Get-Content $FilePath | Out-String | ConvertFrom-Json  

    #======STUCK IN HERE=============
    # How can dynamically navigate through the file nodes like this?

    $file.properties.availability.frequency

    #and set the corresponding value

    $file.properties.availability.frequency = $value

   }
}

I'm new in the PowerShell world and I don't know if there is a cmdlet that helps me to do what I need.

Any suggestion will be appreciated.

EDIT

Simple Path

$snapshot.properties.availability.frequency

Path with arrays

$snapshot.properties.activities[0].scheduler.frequency

this is an example of the JSON file with arrays Destination file

and this is the result Destination file updated

Any idea on what could be happening?

1 Answer 1

2

Invoke-Expression will help you.

#Go through all the arrays (files)
Foreach($file in $files)
{
    $snapshot = (Get-Content ("./" + $file + ".json") | ConvertFrom-Json)

    # get config corresponds to the $file
    $config = Invoke-Expression ('$json.' + $file)

    # set value according to the config
    Invoke-Expression ('$snapshot.' + $config.name + "='" + $config.value + "'")

    # $snapshot.properties.availability.frequency
    # -> $Frequency$
}

Edit

You have to use ConvertTo-Json -Depth 100 to write the result to JSON file properly (specify the appropriate depth according to your JSON files.). Without -Depth option, you will get the result like "@{type=Copy, typeProperties=;, ...}".

Sign up to request clarification or add additional context in comments.

5 Comments

The solution you propose works perfectly if I have to navigate through a simple path but it doesn't work if I have a path with arrays. Please see the edited part in my question
I made these files and confirmed properties.activities[0].scheduler.frequency replace target variable propery. What should be done with "Path with arrays" style config? gist.github.com/satob/3b67553c6fc0bfd2f989ca36113fcea2
Yes, the replacement is done correctly. If I navigate through $snapshot.properties.activities[0].frequency the value is $frequency$ but I forgot to mention that I want to set the content of the $snapshot in the original file by using this command $snapshot | ConvertTo-Json | set-content $FilePath and here is where the problem comes...the JSON file is not updated properly as you can see in the Destination file updated
You mean, the result should contain the string like { "type": "Copy", "typeProperties": ... }, but you got the result like "@{type=Copy, typeProperties=;, ...}", right? I added additional information to the answer.
Great!!... the ConvertTo-Json -Depth 100 command resolved the problem. Thanks a lot,satob!!.

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.