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

Eno*_*han 3 parameters powershell escaping

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

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

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


param (
    [Parameter(Mandatory=$true)][string]$password
)
Run Code Online (Sandbox Code Playgroud)

上面的代码位于脚本的前面,使控制台提示用户输入。

Invoke-Expression -Command "<path_to_exe> -install $user $password"
Run Code Online (Sandbox Code Playgroud)

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


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

Dre*_*rew 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
Run Code Online (Sandbox Code Playgroud)


mkl*_*nt0 6

您正在使用Invoke-Expression调用外部程序

  • 没有 理由这样做,并且Invoke-Expression通常应该避免:它会导致头痛引用(如你的情况),但是,更重要的是,它可以是一个安全风险,通常有更好的解决方案。

    • 顺便说一句:不幸的是,即使使用直接调用,也可能存在围绕空字符串参数和带有嵌入 "字符的参数的引用挑战。- 见脚注 [1] 和这个答案
  • 如果您改为直接调用外部程序- 正如任何外壳程序,包括 PowerShell 设计的那样 -您的问题可能会消失[1]

& <path_to_exe> -install $user $password
Run Code Online (Sandbox Code Playgroud)

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


另外,如果您确实发现自己需要对一字符中的任何字符进行转义,请-replace字符类, 一起使用[...]

注意:这不是传递参数所必需的,既不是传递给外部程序,如上所示,也不是传递给 PowerShell 命令;但是,由于 PowerShell 对"传递给外部程序的参数值中嵌入的字符的处理中断,您可能必须"(仅)转义字符,如\"[1]

& <path_to_exe> -install $user $password
Run Code Online (Sandbox Code Playgroud)

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

有关-replace运算符的更多信息,请参阅此答案


[1] 有一个字符仍然会导致问题:embedded "。由于历史原因,PowerShell没有正确地将嵌入"正确传递给外部程序,并且烦人地需要手动\转义-有关详细信息,请参阅此 GitHub 问题。适用于您的解决方案:& <path_to_exe> -install $user ($password -replace '"', '\"'