你正在使用Invoke-Expression
调用外部程序:
-
There's no这样做的理由, and Invoke-Expression一般应避免 https://blogs.msdn.microsoft.com/powershell/2011/06/03/invoke-expression-considered-harmful/:它会导致引用头痛(就像您的情况一样),但更重要的是,它可能会带来安全风险,并且通常有更好的解决方案。
- 顺便说一句:不幸的是,即使直接调用,也可能存在围绕空字符串参数和带参数的引用挑战embedded
"
字符。 - 参见脚注 [1] 和这个答案 https://stackoverflow.com/a/59036879/45375.
-
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 的呼叫接线员 https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_operators#call-operator-, 仅当可执行文件的路径被引用时才需要(例如,"C:\Program Files\foo.exe"
)和/或通过指定variable参考(例如,$HOME\foo.exe
);否则,您可以按原样调用可执行文件(例如,调用cmd.exe
,使用类似的东西
cmd /c 'echo hi'
).
分别地,如果您确实发现自己需要转义中的任何字符set字符数,使用-replace
with a 字符类 https://learn.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-language-quick-reference#character-classes, [...]
:
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.
欲了解更多信息-replace
运算符,参见这个答案 https://stackoverflow.com/a/40683667/45375.
[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 in Windows PowerShell and PowerShell (Core) versions up to v7.2.x - see this answer https://stackoverflow.com/a/59036879/45375 for details.
Applied to your solution:& <path_to_exe> -install $user ($password -replace '"', '\"'
)