4

我正在使用此代码在服务器上执行远程代码(MSI 安装)。通过脚本传递双引号是行不通的。我尝试了下面给出的两种变体(#3和#4)以及输出。

输入#1(测试命令中双引号的简单案例)

powershell.exe -inputformat none -File client.ps1 -target 1.2.3.4 -port 5985 -password "pass" -username "user" -command "echo hello"

输出(作品)

hello

输入#2(可以理解,这行不通)

powershell.exe -inputformat none -File client.ps1 -target 1.2.3.4 -port 5985 -password "pass" -username "user" -command "echo hello world"

输出

hello
world

输入#3

powershell.exe -inputformat none -File client.ps1 -target 1.2.3.4 -port 5985 -password "pass" -username "user" -command "echo `"hello world`""

输出(另一个词怎么了?)

hello

输入#4

powershell.exe -inputformat none -File client.ps1 -target 1.2.3.4 -port 5985 -password "pass" -username "user" -command @'
>> echo "hello world"
>> '@
>>

输出(同样,第二个单词丢失)

hello

如果回显有效,我应该能够在我正在做的基于运行空间的使用中合并对 MSI 命令的更改。


如果我使用以下设置,MSI 设置工作正常。注意单引号。

msiexec /qn /i 'C:\setups\My Software.msi'

但是,我需要传递公共属性,并且 MSI 不喜欢其中的单引号。尝试运行以下命令会打开 MSI 参数对话框。

msiexec /qn /i 'C:\setups\My Software.msi' MYPROP='My Value'

从服务器上的本地命令提示符运行它可以正常工作。

msiexec /qn /i "C:\setups\My Software.msi" MYPROP="My Value"
4

2 回答 2

6

如果您从 cmd.exe 调用它,则必须根据 CMD 的规则转义双引号。

powershell.exe -command "echo \"hello world\""

输出

hello world

就个人而言,我建议尽可能避免从命令行传递参数。也许您可以将参数值存储在文件中(例如,序列化的 XML、JSON),并让 PowerShell 脚本读取该文件?

更好的是,我建议msiexec.exe通过Start-Processcmdlet 对进程(例如 )进行任何处理。这样,您可以-ArgumentList在变量中建立参数的值,然后保证它会完全按照您想要的方式传递,此外,您将不受cmd.exe.

考虑以下:

$ArgumentList = '/package "c:\setups\My Software.msi" /passive /norestart /l*v "{0}\temp\Install My Software.log" MYPROP="My Value With Spaces"' -f $env:windir;
Start-Process -FilePath msiexec.exe -ArgumentList $ArgumentList;
于 2013-12-29T21:35:13.243 回答
0

或者,您可以将命令编码为 base64 字符串,以避免意外解释任何特殊字符,例如封装的双引号。

powershell.exe -EncodedCommand "ZQBjAGgAbwAgACIAaABlAGwAbABvACAAdwBvAHIAbABkACIA"

结果

hello world

ZQBjAGgAbwAgACIAaABlAGwAbABvACAAdwBvAHIAbABkACIA ....是这个的base64表示。看看我如何不需要逃避任何事情。

echo "hello world"
于 2013-12-30T02:31:32.310 回答