4

I've been pulling my hair out trying to figure out why Powershell was ignoring a command line parameter and I think I finally found that somehow a trailing backslash on a string parameter confuses parameter parsing.

I have

param (
    [Parameter(Mandatory=$true)][String]$p1,
    [Parameter(Mandatory=$true)][String]$p2
)

Write-Output "p1:$p1, p2:$p2"

Ultimately, I need to invoke something like this from the Windows task scheduler which means using powershell.exe as the program and adding this script and arguments as args.

In production, p1 is a file path. So I try:

PS C:\source> C:\Windows\System32\windowspowershell\v1.0\powershell.exe -ExecutionPolicy Bypass -File  .\myScript.ps1 -p1 'C:\Program Files\' -p2 asdf

cmdlet myScript.ps1 at command pipeline position 1
Supply values for the following parameters:
p2:

Why the prompt? The parameter is right there. I eventually stumbled on removing the trailing backslash for p1:

PS C:\source> C:\Windows\System32\windowspowershell\v1.0\powershell.exe -ExecutionPolicy Bypass -File  .\myScript.ps1 -p1 'C:\Program Files' -p2 asdf
p1:C:\Program Files, p2:asdf

Is this a bug?

Chris Nelson
  • 3,519
  • 7
  • 40
  • 51
  • The backslash used to be an escape cahrachter. So if you place it in front of a charachter with a special meaning it breaks this meaning. – Olaf Feb 24 '20 at 22:19
  • @Olaf I thought in powershell the `` ` `` is the escape character and even then they didn't take effect in `'`-strings. Is the newly called powershell reinterpreting the arguments after Chris' shell had already and fed it as input? – Hashbrown Feb 24 '20 at 22:54
  • @Hashbrown It is _an_ escape charachter - not _the_. The backtick is another one. You can even see it when you pay attention to the syntax highlighting. In the second example the colour after the second single quote changes. In the first it does not. In the answer from js2010 down here you can see that escaping the escape charachter just solves the issue. ;-) – Olaf Feb 24 '20 at 23:13
  • @Olaf I really hope this isn't the case, that pushes pwsh back into the dark ages of cmd with inconsistent escaping rules. It might solve the issue, but the question was *why*. I can do `echo 'bob\'` in a pwsh terminal right now and even `powershell -ExecutionPolicy Bypass -Command echo 'bob\'` and it prints `bob\ `, so I'm not even seeing Chris' issue. This is in `PSVersion 5.1.17134.858`, maybe it only happens in if you call a `-File`? – Hashbrown Feb 24 '20 at 23:24
  • I don't see a problem with that. Just keep in mind that there are some charachters with special meaning. If you come across some of them deal with it. You may read more about here [about_Quoting_Rules](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_quoting_rules?view=powershell-7) and here [about_Special_Characters](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_special_characters?view=powershell-7). – Olaf Feb 25 '20 at 00:09
  • @Olaf I hope you're joking. Let's say you accept user input to pass to a function (assuming its the child shell doing the interpreting, not the parent). How do you know there's a special character? How do you "deal with it" so that it's faithfully delivered to the script? Also why does my example work but not OPs script? It doesnt negate the fact that `\ ` should not do anything in `'`. Their question is `why is this breaking?` and `is this a bug?`, they already have a workaround – Hashbrown Feb 25 '20 at 02:25
  • 1
    I hope the [linked answer](https://stackoverflow.com/a/59960203/45375) explains it all. In short: PowerShell's behind-the-scenes-re-quoting-with-double-quotes is broken in _Windows PowerShell_, but has since been fixed in PowerShell [Core]. – mklement0 Feb 25 '20 at 02:36

1 Answers1

1

This works for me in cmd (double backslash and double quotes). I guess the backslash is an escape character for the powershell command line options.

C:\Windows\System32\windowspowershell\v1.0\powershell.exe -ExecutionPolicy Bypass -file .\myScript.ps1 -p1 "C:\Program Files\\" -p2 asdf

p1:C:\Program Files\, p2:asdf
js2010
  • 23,033
  • 6
  • 64
  • 66