34

I'm using a powershell script to generate a config file with database passwords and the like. The normal use of this script is to generate-and-use a password, but for a fleeting moment, I need to access a fellow developer's database, so I need to pass the password into the powershell script.

The problem is that the password is gibberish that includes ampersands, semicolons, and curly braces. How can I pass this into a command-line invocation of powershell? (This answer and this other answer are helpful, but doesn't help with the semicolons and curly braces.)

Here's what I've tried:

powershell .\makeConfig.ps1 -password "xxx<xxxx;xxxxx&x.xxxx}xx/xxx" -otherparam 3

Result: An error message: The ampersand (&) character is not allowed. The & operator is reserved for future use; wrap an ampersand in double quotation marks ("&") to pass it as part of a string.

powershell .\makeConfig.ps1 -password "xxx<xxxx;xxxxx`"&`"x.xxxx}xx/xxx" -otherparam 3

Result: Doing a write-host of the $password only gives the string up to the semicolon. Also, -otherparam has its default value rather than the value that I passed in to the command line.

powershell .\makeConfig.ps1 -password "xxx<xxxx`;xxxxx`"&`"x.xxxx}xx/xxx" -otherparam 3

Result: write-host $password now prints up to the first backtick before the quote. And yes, it outputs the backtick, which seems to show that everything is parsing all wrong. Oh, and one of the other functions called in the script threw an exception I haven't seen before (Exception calling "AcquireToken" with "4" argument(s): "authentication_canceled: User canceled authentication"), which suggests that the param parsing was completely hosed in a new and fascinating way. Here's what write-host $password produced:

xxx<xxxx;xxxxx`


powershell .\makeConfig.ps1 -password "xxx<xxxx`";`"xxxxx`"&`"x.xxxx}xx/xxx" -otherparam 3

Result: write-host $password now prints up to the first backtick before the quote. And the second parameter is in the default state. (i.e., same result as last time.) On the plus side, the exception thrown in the previous example didn't crop up.

So how do I pass in arbitrary ASCII strings to powershell string params from the Windows command line? Or at least, how do I escape semicolons, ampersands, and curly braces?

Community
  • 1
  • 1
PotatoEngineer
  • 1,572
  • 3
  • 20
  • 26

4 Answers4

36
powershell .\makeConfig.ps1 -password "'xxx<xxxx;xxxxx&x.xxxx}xx/xxx'" -otherparam 3

Here

  • outer " double quotes would escape all cmd poisonous characters e.g. <, & etc. excepting " itself and % percentage sign (and ! exclamation mark if delayed expansion is enabled) while
  • inner ' apostrophes (single quotes) would escape all powershell ones (excepting ' apostrophe itself).

However, exceptions noticed above could be escaped as well… Based on both Escape characters, Delimiters and Quotes articles:

JosefZ
  • 28,460
  • 5
  • 44
  • 83
  • 2
    This didn't work for me. I was trying to set heroku config as a mongo url and it had an &. I had to swap the quotes. so for me instead of doing `"'blah'"`, I had to do `'"blah"'`. – Akshay Kumar Jul 03 '21 at 06:20
  • 2
    @Akshay try `"""bl&ah"""` instead of `"'bl&ah'"`; received string (check `$args`) would become `"bl&ah"` instead of `'bl&ah'`. – JosefZ Jul 03 '21 at 09:52
  • This doesn't seem to work on PowerShell 6. – Pedro Lamarão Jan 02 '22 at 22:26
19

I'm running firebase using a powershell script. I solved the problem by using triple double-quotes like this: firebase deploy --token "$firebaseToken" --project "$firebaseProject" --message """$releaseMessage""". The URL is in the $releaseMessage, and the ampersand doesn't cause a problem anymore.

Noxxys
  • 879
  • 1
  • 9
  • 19
  • 4
    After trying single quotes, double quotes, putting backtick in front of ampersand, and mix them like the accepted answer, none worked. But using triple double-quotes worked! – BlackMiracle May 21 '21 at 07:29
  • 1
    Exact same experience here as BlackMiracle, first time my script works 100% flawlessly after trying everything else. – Smogshaik Jun 21 '22 at 11:06
3

I had the same issue passing a SAS token which consisted of a GET URI with ampersand query strings.

the """$sas""" worked for me - see below

az storage blob copy start `
    --destination-blob $destinationVHDFileName `
    --destination-container $storageContainerName `
    --account-name $storageAccountName `
    --account-key $storageAccountKey `
    --source-uri """$sas""" `
    --debug `
    --verbose
JGilmartin
  • 8,683
  • 14
  • 66
  • 85
0

Use --%, the stop parsing token.

powershell .\makeConfig.ps1 -password --% xxx<xxxx;xxxxx&x.xxxx}xx/xxx -otherparam 3
tm1
  • 1,180
  • 12
  • 28