How to escape special characters in PowerShell?

You’re using Invoke-Expression to call an external program:

  • There’s no reason to do that, and Invoke-Expression should generally be avoided: it causes quoting headaches (as in your case), but, more importantly, it can be a security risk and there are typically better solutions.

    • As an aside: Unfortunately, even with direct invocation there can be quoting challenges around empty-string arguments and arguments with embedded " chars. – see footnote [1] and this answer.
  • If you instead invoke the external program directly – as any shell, including PowerShell is designed to do – your problem will likely go away:[1]

& <path_to_exe> -install $user $password

Note: &, PowerShell’s call operator, is only needed if your executable’s path is quoted (e.g, "C:\Program Files\foo.exe") and/or is specified via a variable reference (e.g., $HOME\foo.exe); otherwise, you can invoke the executable as-is (e.g., to invoke cmd.exe, use something like
cmd /c 'echo hi').


Separately, if you do ever find yourself needing to escape any of the characters in a set of characters, use -replace with a character class, [...]:

Note: This is not necessary for passing arguments, neither to external programs, as shown above, nor to PowerShell commands; however, due to PowerShell’s broken handling of " characters embedded in argument values passed to external programs, you may have to escape " characters (only), as \"[1].

PS> 'a*b\c~d;e(f%g?h.i:j@k/l' -replace '[*\\~;(%?.:@/]', '`$&'
a`*b`\c`~d`;e`(f`%g`?h`.i`:j`@k`/l  # all chars. inside [...] were `-escaped

Note: Since \ has special meaning even inside a character class, it had to be escaped as \\ – all other chars. are used as-is.

For more information about the -replace operator, see this answer.


[1] There is one character that still causes problems: embedded ". For historical reasons, PowerShell does not properly pass embedded " correctly to external programs, and annoyingly requires manual \-escaping – see this GitHub issue for details.
Applied to your solution:& <path_to_exe> -install $user ($password -replace '"', '\"')

Leave a Comment