通过PowerShell + WinRM传递双引号

时间:2013-12-29 21:24:06

标签: powershell windows-installer winrm runspace

我正在使用此code在服务器上执行远程代码(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

如果echo工作正常,我应该能够在基于运行空间的用法中将更改合并到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"

2 个答案:

答案 0 :(得分:6)

如果你是从cmd.exe调用它,你必须根据CMD的规则逃避双引号。

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

输出

hello world

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

更好的是,我建议通过msiexec.exe cmdlet对进程(例如Start-Process)进行任何处理。这样,您可以在变量中为-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;

答案 1 :(得分:0)

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

powershell.exe -EncodedCommand“ZQBjAGgAbwAgACIAaABlAGwAbABvACAAdwBvAHIAbABkACIA”

结果

hello world

ZQBjAGgAbwAgACIAaABlAGwAbABvACAAdwBvAHIAbABkACIA ....是base64的代表。看看我怎么不需要逃避任何事情。

echo "hello world"