When my PowerShell script runs, it prompts the user for a password parameter. That password can contain any number of special characters like *\\~;(%?.:@/ That password is then used as a parameter for a .exe command, but it is often incorrect due to some special characters not being escaped properly.
An example past password was $(?-.?-(. The only characters I needed to escape was '(', which I replaced with '`(' to make it work. However, that password is now expired. The new password is something like *\\~;~(%?.:@/ *NOTE: these passwords have random numbers and letters mixed into them as well, but have been redacted.
The only characters in the new password NOT in the first are *\\~;%:@/ Is there an easy way to escape all characters and just take any user input as it is? If not, would someone mind helping me escape these special characters?
param (
[Parameter(Mandatory=$true)][string]$password
)
The above code prefaces the script, causing the console to prompt for user input.
Invoke-Expression -Command "<path_to_exe> -install $user $password"
^this is the command that uses that password parameter
I have tried many other suggestions on Stack Overflow, Reddit, and other various coding forums/blogs and none have worked. Any help is much appreciated!
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.
"
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 (eg, "C:\\Program Files\\foo.exe"
) and/or is specified via a variable reference (eg, $HOME\\foo.exe
); otherwise, you can invoke the executable as-is (eg, to invoke cmd.exe
, use something likecmd /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 '"', '\\"'
)
Using the below will escape the characters using the escape prefix you mentioned. The normal escape prefix is \\ as shown below. I have set it this way so it is easier for you to add additional characters to escape or change the escape prefix.
function Set-EscapeCharacters {
Param(
[parameter(Mandatory = $true, Position = 0)]
[String]
$string
)
$string = $string -replace '\*', '`*'
$string = $string -replace '\\', '`\'
$string = $string -replace '\~', '`~'
$string = $string -replace '\;', '`;'
$string = $string -replace '\(', '`('
$string = $string -replace '\%', '`%'
$string = $string -replace '\?', '`?'
$string = $string -replace '\.', '`.'
$string = $string -replace '\:', '`:'
$string = $string -replace '\@', '`@'
$string = $string -replace '\/', '`/'
$string
}
$Password = Set-EscapeCharacters $Password
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.