如何在PowerShell中转义特殊字符?

问题描述 投票:0回答:3

当我的 PowerShell 脚本运行时,它会提示用户输入密码参数。该密码可以包含任意数量的特殊字符,例如 *\~;(%?.:@/ 然后将该密码用作 .exe 命令的参数,但由于某些特殊字符未正确转义,该密码通常不正确。

过去的密码示例是 $(?-.?-(。我需要转义的唯一字符是 '(',我将其替换为 '`(' 以使其正常工作。但是,该密码现已过期。新密码密码类似于 *\~;~(%?.:@/ *注意:这些密码也混合有随机数字和字母,但已被编辑。

新密码中唯一不在第一个密码中的字符是 *\~;%:@/ 有没有一种简单的方法可以转义所有字符并按原样接受任何用户输入?如果没有,有人介意帮我逃脱这些特殊字符吗?


param (
    [Parameter(Mandatory=$true)][string]$password
)

上面的代码作为脚本的前缀,导致控制台提示用户输入。

Invoke-Expression -Command "<path_to_exe> -install $user $password"

^这是使用该密码参数的命令


我在 Stack Overflow、Reddit 和其他各种编码论坛/博客上尝试了许多其他建议,但没有一个有效。非常感谢任何帮助!

powershell parameters escaping
3个回答
9
投票

您正在使用

Invoke-Expression
调用外部程序:

  • 没有没有理由这样做,而且

    Invoke-Expression
    通常应该避免:它会导致引用头痛(就像你的情况一样),但更重要的是,它可能存在安全风险,并且通常存在更好的解决方案。

    • 顺便说一句:不幸的是,即使直接调用,空字符串参数和带有 embedded
      "
      字符的参数也可能存在引用挑战。 - 请参阅脚注 [1] 和这个答案
  • 如果您直接调用外部程序 - 正如任何 shell(包括 PowerShell)的设计目的 - 您的问题可能会消失[1]

& <path_to_exe> -install $user $password

注意:仅当可执行文件的路径被引用(例如,

&
)和/或通过变量引用(例如,
"C:\Program Files\foo.exe"
)指定时,才需要$HOME\foo.exe,PowerShell的
调用运算符
;否则,您可以按原样调用可执行文件(例如,要调用
cmd.exe
,请使用类似
cmd /c 'echo hi'
的内容)。


另外,如果您发现自己需要转义字符集中的任何字符,请使用-replace

字符类[...]

注意:对于传递参数来说,这不是所必需的,无论是传递给外部程序(如上所示),还是传递给 PowerShell 命令;但是,由于 PowerShell 对传递给 外部程序

 的参数值中嵌入的 
" 字符的处理被破坏,您可能必须(仅)转义 "
 字符,如 
\"
[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

注意:由于 \

 即使在字符类中也具有特殊含义,因此必须将其转义为 
\\
 - 所有其他字符。按原样使用。

有关

-replace

 运算符的更多信息,请参阅 
此答案


[1] 有一个one字符仍然会导致问题:嵌入的"

。由于历史原因,PowerShell 无法正确地将嵌入的 
" 正确地传递给 外部程序
,而且令人烦恼的是,在 Windows PowerShell 和 v7.2 之前的 PowerShell(核心)版本中需要 
manual \-escaping
。 x - 有关详细信息,请参阅
此答案。 应用于您的解决方案:& <path_to_exe> -install $user ($password -replace '"', '\"'
    

使用下面的命令将使用您提到的转义前缀对字符进行转义。正常的转义前缀是 \ ,如下所示。我这样设置是为了让您更容易添加额外的字符来转义或更改转义前缀。

6
投票
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

没有完全回答OP关于Power-Shell脚本编写的问题,但是谷歌搜索

0
投票
带来了这里,所以下面的内容对于那些在交互式shell中寻找转义的人来说可能很有用。

如果您需要在具有特殊字符(例如 JSON)的字符串中进行变量扩展,用作命令的输入(例如 

curl.exe
),请使用

"

 转义 
\
`
:
curl.exe -X POST -d "{`\`"username`\`":`\`"$user`\`",`\`"password`\`":`\`"$pw`\`"}" --trace-ascii curl.log "https://exampled.com/api"

因此发送到
curl.exe
的实际字符串将是:

{\"username\":\"test\",\"password\":\"foo\"}

在curl跟踪日志中,您可以看到实际发送的数据是有效的JSON:
=> Send data, 36 bytes (0x24)
0000: {"username":"test","password":"foo"}


© www.soinside.com 2019 - 2024. All rights reserved.