0

I have a script that I want to do variable substitution on a json file.

It takes json file A and json file B and converts it into a dynamic object.

So you end up with something like this:

For Json File A:

Json file A key Json file A value
Age ENTER VALUE
ADDRESS ENTER VALUE

For Json File B:

Json file B key Json file B value
Age 38
ADDRESS 10 example lane

If the keys match then the value from Json File B will be subbed into Json File A where the keys match.

So Json File A should end up looking like:

Json file A key Json file A value
Age 38
ADDRESS 10 example lane

I am able to loop through and find matching keys and set the value of Json File A to the Value from Json File B for that Key.

However, I don't know how to get the new value into the actual json file A

Here are the relevant snippets of code:

$appSettings = Get-Content $JsonFileA -Raw | ConvertFrom-Json | Get-LeafProperty 

        if ($keyAA -eq $keyBB ) {
            write-host "$keyAA and $keyBB match"
            $valueAA=$valueBB
            write-host "new appsettings value is now $valueAA"
            
# Save newly populated jsonfile to a new file
            $appSettings | ConvertTo-Json -Depth 4 | Set-Content "path/to/output/file"
        }

The write-host "new appsettings value is now $appvalue" line shows that it has done what i want and updated the value for Json File A to the value from Json File B for the matching key

But it is not saving the value to the output file. The output file is still just what the original Json File A looks like

FULL CODE for context:

function Get-LeafProperty {
  param([Parameter(ValueFromPipeline)] [object] $InputObject, [string] $NamePath)
  process {   
    if ($null -eq $InputObject -or $InputObject -is [DbNull] -or $InputObject.GetType().IsPrimitive -or $InputObject.GetType() -in [string], [datetime], [datetimeoffset], [decimal], [bigint]) {
      [pscustomobject] @{ NamePath = $NamePath; Value = $InputObject }
    }
    elseif ($InputObject -is [System.Collections.IEnumerable] -and $InputObject -isnot [System.Collections.IDictionary]) {
      $i = 0
      foreach ($o in $InputObject) { Get-LeafProperty $o ($NamePath + '[' + $i++ + ']') }
    }
    else { 
      $props = if ($InputObject -is [System.Collections.IDictionary] -or $InputObject -is [System.Collections.IEnumerable]) { $InputObject.GetEnumerator() } else { $InputObject.psobject.properties }
      $sep = '.' * ($NamePath -ne '')
      foreach ($p in $props) {
        Get-LeafProperty $p.Value ($NamePath + $sep + $p.Name)
      }
    }
  }
}

$appSettings = Get-Content $jsonfileA -Raw | ConvertFrom-Json | Get-LeafProperty 

$secrets = Get-Content $jsonfileB -Raw | ConvertFrom-Json | Get-LeafProperty 

$leafProperties | ForEach-Object {
    $keyAA = $_.NamePath
    $valueAA = $_.Value

    $secrets | ForEach-Object {
        $keyBB = $_.NamePath
        $keyBB = $_.Value

        if ($keyAA -eq $keyBB ) {
            write-host "$keyAA and $keyBB match"
            $valueAA=$valueBB
            write-host "new appsettings value is now $valueAA"
            $appSettings | ConvertTo-Json -Depth 4 | Set-Content "path/to/output/file"
        }
    }
}


 
polo
  • 155
  • 4
  • 11
  • What is `Get-LeafProperty`? Where do you define `$keyAA`, '$keyBB', '$valueAA', and '$valueBB'? Where do you apply the updated value back to `$appSettings`? We need more than what you gave us. – TheMadTechnician Feb 02 '23 at 23:21
  • @TheMadTechnician added full code now - sorry was just try to keep it short and included the relevant bits. "Where do you apply the updated value back to $appSettings" This is what i need help with – polo Feb 03 '23 at 08:01
  • Oof, you're flattening nested arrays. You have no way to convert back to those nested arrays unless you can *guarantee* that your namepath will **never** contain `[#]` or `.`. If that is the case you'd need a function to parse namespace back to a nested path to set values. There must be a better way to compare values, but I can't think of it off the top of my head. – TheMadTechnician Feb 03 '23 at 19:11
  • @TheMadTechnician ah thanks for the info, at least i'm not missing something obvious! - yeah these nested arrays are killing me. The Namepath does contain "." and wasn't able to set it back in the Json file but at least now i Know it wasnt just something i was doing – polo Feb 03 '23 at 21:27
  • Not really an answer, but I feel like this module would help you if you wanted to take a little time to figure out the results, parse out what you need, and apply the changes: https://github.com/choovick/ps-jsonutils – TheMadTechnician Feb 03 '23 at 21:38

0 Answers0