1

I am trying to run AWS CLI in Powershell 7 with a JSON string as parameter. AWS docs make it seem straightforward:

aws route53 ... --change-batch '{"Changes":[{"Action":"UPSERT"}]}'

however, I get an error:

Error parsing parameter '--change-batch': Invalid JSON: Expecting property name enclosed in double quotes: line 1 column 2 (char 1) JSON received: {Changes:[{Action:UPSERT ...

So, it looks like double quotes are stripped at some point.

If I escape the quotes, command works:

aws route53 ... --change-batch '{\"Changes\":[{\"Action\":\"UPSERT\"}]}'

Now, I am trying to use a variable:

aws route53 ... --change-batch '{\"Changes\":[{\"Action\":\"UPSERT\", \"Value\":\"$MY_IP\"}]}'

but the variable is not resolved; that is, $MY_IP is passed to the server. I tried putting the whole string in double-quotes - but it looks like with double quotes internal quotes are removed even if I escape them. Also with backticks - it works as command continuation. I am looking at Microsoft docs - but the results I am getting are clearly different.

I don't think the problem has anything to do with AWS, but AWS CLI gave me a super twisted test case.

0

1 Answer 1

1
  • Fundamentally, PowerShell only performs string interpolation in double-quoted strings ("..."), also known as expandable strings: see this answer.

  • The surprising and unfortunate need to explicitly \-escape embedded " chars. in arguments for external programs applies irrespective of which quoting style you use, up to at least PowerShell 7.2.x: see this answer.

Thus, since you need a "..." string for string interpolation (so that variable reference $MY_IP is expanded to its value), you need two layers of escaping of embedded ":

  • `" (or "") in order to satisfy PowerShell's syntax requirements...

  • ... and this escape sequence must additionally be escaped with \ in order for the external program to see the embedded " as such.

Therefore:

# Inside "...", pass-through " must be escaped as \`" (sic)
aws route53 ... --change-batch "{\`"Changes\`":[{\`"Action\`":\"`UPSERT\`", \`"Value\`":\`"$MY_IP\`"}]}"

You can ease the pain with the help of an (expandable) here-string, which obviates the need to escape the embedded " for PowerShell's sake:

# A here-string obviates the need to escape " for PowerShell's sake.
aws route53 ... --change-batch @"
{\"Changes\":[{\"Action\":\"UPSERT\", \"Value\":\"$MY_IP\"}]}
"@

Another option is to perform the \-escaping after the fact, programmatically:

aws route53 ... --change-batch (@"
{"Changes":[{"Action":"UPSERT", "Value":"$MY_IP"}]}
"@ -replace '"', '\"')
Sign up to request clarification or add additional context in comments.

4 Comments

@Felix :) The need for the extra \-escaping is definitely obscure and a nuisance since v1 - a fix is being tested (as an experimental feature in preview versions of 7.3), but it may be opt-in when it becomes official. If it weren't for this, all you'd need to remember is that in PowerShell ` is the escape character, not \ - the distinction between '...' (verbatim) and "..." (interpolating) strings is more or less the same.
Now, if only somebody could tell AWS to updated their docs!
@Felix, yeah, that seems broken - there's an Edit this page on GitHub link at the bottom, though... - github.com/awsdocs/aws-cli-user-guide/tree/master/doc_source/…
I upgraded to powershell 7.3 - and as you said, it is much cleaner!

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.