Add values to an array and send it as json payload - Powershell Azure

Viewed 284

I am using powershell (specifically Azure CLI) to get data from a service, add a value to a list and send a patch/post to an URL.

This is the URL to get the list of data:

$uriList = az rest --method get --uri "https://graph.microsoft.com/beta/applications/$objectId" --header "$header" --query spa.redirectUris | ConvertFrom-Json

This returns an array of strings.

['a', 'b', 'c', 'd', 'e']

if ($uriList -notcontains "f") {
    $uriList  += "f"
}

$uriListJSON = $uriList | ConvertTo-Json

Above, I have added "f" to the array and I want to send it to the url as follows:

$body = "{spa:{redirectUris: $uriListJSON}}"

az rest --method patch --uri "https://graph.microsoft.com/beta/applications/$objectId" --headers "$header" --body "$body"

I get an error:

Unable to read JSON request payload. Please ensure Content-Type header is set and payload is of valid JSON format."

Please advice on what I am doing wrong. I outputted uriListJSON to a file and ran it against a json validator and it passed.

When I hardcode everything to a url like

az rest --method patch --uri "https://graph.microsoft.com/beta/applications/$objectId" --headers $header --body "{spa: {redirectUris: ['a', 'b', 'c', 'd', 'e', 'f']}}"

it works like a charm.

1 Answers

Your from-and-to JSON conversion results in a string with - standards-compliant - embedded double-quoting ("):

PS> ("['a', 'b', 'c', 'd', 'e']" | ConvertFrom-Json) + 'f' | ConvertTo-Json -Compress

["a","b","c","d","e","f"]

Since you're passing the resulting string to an external program - az - the sad reality as of PowerShell 7.2 is that an extra, manual layer of \-escaping of embedded " characters is required in arguments.
This may get fixed in a future version, which may require opt-in. See this answer for details.

Therefore:

$uriListJSON = ("['a', 'b', 'c', 'd', 'e']" | ConvertFrom-Json) + 'f' | ConvertTo-Json -Compress

$body = "{ \`"spa\`": { \`"redirectUris\`": $($uriListJSON -replace '"', '\"') } }"

Note that while it may not be necessary for az, the above uses a strictly standards-compliant JSON string in which the property names of the verbatim part of your JSON string too are "..."-quoted, which requires both escaping for PowerShell (`") and manual \-escaping for the external program; in combination: \`"

Related