1
 {
    "$schema": "a",
    "contentVersion": "b",
    "extensions": [   
    {
      "Name": "c",
      "Type": "d",
      "Version": "e",
      "ConnectionProperties": {
        "MaxExecutionTime": "f",
        "Authentication": {
          "Type": "g",
          "Reference": {
            "Provider": "h",
            "Parameters": {
              "SecretId": "i"
            }
          },
          "Properties": {
            "ApplicationId": "j",
            "TenantId": "k"
          }
        }
      },
      "payloadProperties": {
        "ConnectionString": {
          "Value": "l"
        },
        "KqlSasUri": {
          "reference": {
            "path": "m",
            "enableScopeTagBindings": "n"
          }
        },        
        "DatabaseName": {
          "Value": "o"
        }
      },
      "repeatOver": [
        {
          "name": "p",
          "file": "q",
          "database": "r"
        }        
      ]
    }
  ]
}

Above is the json file, I wish to append to repeatOver array using powershell script

$getContentfromDestinationJson = Get-Content $pathToDestinationJson -Raw | ConvertFrom-Json

$destinationExtension = $getContentfromDestinationJson.extensions

Write-Host $destinationExtension

Output is --

@{Name=a; Type=b; Version=c; ConnectionProperties=; payloadProperties=; repeatOver=System.Object[]}

Also, when I try to write append to this repeatOver array in this json.

Note- the below code is in a for loop, I want to append this multiple times to the array..

 for ($i=0; $i -le 3; $i++) {    

   $toWrite= [PSCustomObject]@{        
            name     = 'd'
            file     =  'e'
            database = 'f'  
        }

   $destinationExtension.repeatOver += (ConvertTo-Json -InputObject $toWrite -Depth 3)

 }

I see this error :

  Method invocation failed because [System.Management.Automation.PSObject] does not contain a method named 'op_Addition'.

Also, how do I skip adding a $toWrite value if it already exists, by comparing the name field?

2
  • Can you confirm the syntax on your JSON is correct? I copied and pasted your JSON code sample into an editor and was getting an "end of file expected" error at the colon immediately after "extensions". Once I enclosed all of the JSON inside { }, the syntax errors disappeared. I also ran your code against my corrected JSON and had no problems outputting the value for $destinationExtension.repeatOver. Commented Jun 25, 2021 at 18:54
  • Thank you for your reply :)Appreciate it. Also, I have edited with the exact json file...it didn't work for me... I had a question, were you able to append $toWrite to the source json file? does it reflect in the file? Commented Jun 25, 2021 at 19:44

2 Answers 2

1

You would need to access the psobject Properties to update that property, I would love to see if there is an easier way of doing this.

Assuming I have the JSON stored in the $json variable, if I try to update .extensions.repeatOver:

PS /> $json.extensions.repeatOver

name file database
---- ---- --------
p    q    r       

PS /> $json.extensions.repeatOver = @()
The property 'repeatOver' cannot be found on this object. Verify that the property exists and can be set.
At line:1 char:1
+ $json.extensions.repeatOver = @()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : PropertyAssignmentException

To update it you can do it like this:

# Here I'm appending the value from repeatOver with random data
$toAppend = @(
    $json.extensions.repeatOver
    for($i=0; $i -le 3; $i++)
    {    
        [PSCustomObject]@{        
            name     = Get-Random -Maximum 9
            file     = Get-Random -Maximum 9
            database = Get-Random -Maximum 9
        }
    }
)

$json.psobject.Properties.where({ $_.Name -eq 'extensions' }).Value.repeatOver = $toAppend

Testing if it works:

PS /> $json.extensions

Name                 : c
Type                 : d
Version              : e
ConnectionProperties : @{MaxExecutionTime=f; Authentication=}
payloadProperties    : @{ConnectionString=; KqlSasUri=; DatabaseName=}
repeatOver           : {@{name=p; file=q; database=r}, @{name=3; file=4; database=2}, @{name=5; file=3; database=6}, @{name=1; file=0; database=7}...}

PS /> $json.extensions.repeatOver

name file database
---- ---- --------
p    q    r       
3    4    2       
5    3    6       
1    0    7       
6    3    8       

I think this is also relevant: https://github.com/PowerShell/PowerShell/issues/3159

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

2 Comments

this worked! ALso, how do I skip adding a field which already exists, say if name="C" already exists, I don't want to add it to repeatOver array...
@gocoding do you mean exclude adding only the name or the entire row (name, file, database)? If you want to check if C was there you would add an if condition and you can use the -notin operator.
0

Since the extensions is also an array, you need to loop over that to append your object array to the repeatOver array.

# read the json file and convert it
$json = Get-Content -Path 'Path\To\The\JSON_file.json' -Raw | ConvertFrom-Json
# create your new object array
$toWrite = for ($i=0; $i -le 3; $i++) {    
    [PSCustomObject]@{        
        name     = "d$i"
        file     = "e$i"
        database = "f$i"  
    }
}
# loop over the extensions array and append to repeatOver 
$json.extensions | ForEach-Object { $_.repeatOver += $toWrite }

$json | ConvertTo-Json -Depth 6 # | Set-Content -Path 'Path\To\The\Extended_JSON_file.json'

P.S. PowerShell does not produce 'pretty' json. If you need to convert it to properly spaced json, see my function Format-Json

2 Comments

Thank you, this worked :) this did print the content onto the console...in order to write it to the file, do I need to uncomment the set-content path?When I did so, I am seeing this error Set-Content : Cannot find drive. A drive with the name '@{$schema=https' does not exist.
@gocoding Yes, to write the result to file, just uncomment the | Set-Content .. part and change the -Path parameter to a path and filename on your computer. The file Name you can choose any name you want. The folder path of course needs to exist.

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.