10

I have json that looks like this:

{
    "Workflow": [
        {
            "Parameters": {
                "Project": "/Path/To/File",
                "OtherParam": "True"
            }
        }
    ],
    "Overrides": [
        {
            "Special": {
                "Parameters": {
                    "NewParam": "NewStuffGoesHere",
                    "OtherParam": "False"
                }
            }
        }
    ]
}

... where I want to use the Overrides.Special section to add or update fields in the workflow object. In other words, given the json above, I want to do something like this:

$config = Get-Content workflow.json | out-string | ConvertFrom-Json
$configWithOverrides = Merge-Object $config.Workflow $config.Overrides.Special

And end up with something like this:

$configWithOverrides

Parameters
----------
@{Project=/Path/To/File; NewParam=NewStuffGoesHere; OtherParam=False}

I can certainly write the Merge-Object function above to add or update values as needed based on what's in the override section, but it seems there should (could?) be a built-in or one-liner way to handle this.

I tried this:

$test = $config.Workflow + $config.Overrides.Special

...but that doesn't quite work.

$test
Parameters
----------
@{Project=/Path/To/File; OtherParam=True}
@{NewParam=NewStuffGoesHere; OtherParam=False}

This enables adding parameters:

>$test.Parameters.NewParam
NewStuffGoesHere

...but it's not so great for updating them

>$test.Parameters.OtherParam
True
False

Note - in this example, I'm choosing to handle the merge after converting the json to a psobject, but that's not a requirement.

Kev
  • 118,037
  • 53
  • 300
  • 385
Alan
  • 1,045
  • 7
  • 14
  • Possible: http://stackoverflow.com/questions/29670111/powershell-merging-json-files – Matt May 20 '15 at 20:24
  • That solution doesn't work (actually not convinced it works for the problem described there either). I added some more information above to make it clear why a straight '+' of the nodes is inadequate. – Alan May 20 '15 at 20:59
  • Last time I will try: http://stackoverflow.com/questions/29330627/extend-json-with-another-in-powershell/29334164#29334164 perhaps is more what you were leaning to. Although it's a function based answer which you stated you were capable of doing – Matt May 20 '15 at 21:04
  • I have a hunch this is the answer, and is pretty much what I was thinking. I'll go ahead and write (continue) writing this merge while I wait to see if something else exists. Thanks! – Alan May 20 '15 at 21:07
  • It is not build-in (maybe it should) but using this [`Join-Object`](https://www.powershellgallery.com/packages/Join) cmdlet: `$config.Workflow.Parameters | Merge $config.Overrides.Special.Parameters | ConvertTo-Json` → `{"Project":"/Path/To/File","OtherParam":"False","NewParam":"NewStuffGoesHere"}` (see also: [Merge two json objects](https://stackoverflow.com/q/45549909/1701026)) – iRon Nov 18 '19 at 10:26

1 Answers1

7

I have a one-liner to do what you're asking for. Notice that, as far as I know, PowerShell does not deal directly with json strings. But, once converted to PowerShell objects, it's like any other object.

So, firstly, define your json file, and read it as a single string:

# Requires -Version 4
$jsonFile='c:\temp\jsonfile.json'
$jsonObj=@(gc $jsonFile -raw)|ConvertFrom-Json

Define the property upon which you want to merge the json's objects, and the 1st and 2nd objects:

$property='Parameters'
$1=$jsonObj.Workflow.$property
$2=$jsonObj.Overrides.Special.$property

Now, see the one-liner (which I've splitted in 3, for the sake of clarity):

$MergedJson=[pscustomobject]@{
    $property=$2.psobject.properties|%{$11=$1}{$11|add-member $_.name   $_.value -ea Ignore}{$11}
}|ConvertTo-Json

You see? $MergedJson holds the following string (using your json string):

{
    "Parameters":  {
                       "Project":  "/Path/To/File",
                       "OtherParam":  "True",
                       "NewParam":  "NewStuffGoesHere"
                   }
}

Is that what you're looking for?

P.S.: if you swap the roles of $1 and $2, the common parameters' (like OtherParam) values that prevail, change.