问题
I am using this code to execute remote code (MSI installs) on a server. Passing double quote through the script is just not working. I tried two variations as given below (#3 and #4) along with the outputs.
Input #1 (Simple case to test double quotes in the command)
powershell.exe -inputformat none -File client.ps1 -target 1.2.3.4 -port 5985 -password "pass" -username "user" -command "echo hello"
Output (Works)
hello
Input #2 (Understandable, this won't work)
powershell.exe -inputformat none -File client.ps1 -target 1.2.3.4 -port 5985 -password "pass" -username "user" -command "echo hello world"
Output
hello
world
Input #3
powershell.exe -inputformat none -File client.ps1 -target 1.2.3.4 -port 5985 -password "pass" -username "user" -command "echo `"hello world`""
Output (What happened to the other word?)
hello
Input #4
powershell.exe -inputformat none -File client.ps1 -target 1.2.3.4 -port 5985 -password "pass" -username "user" -command @'
>> echo "hello world"
>> '@
>>
Output (Again, the 2nd word is missing)
hello
If the echo works, I should be able to incorporate the changes to the MSI commands in the Runspace based usage I am doing.
MSI setup works fine if I use the following. Notice the single quotes.
msiexec /qn /i 'C:\setups\My Software.msi'
But, I need to pass public properties and MSI does not like single quote in it. Trying to run the following opens up the MSI arguments dialog.
msiexec /qn /i 'C:\setups\My Software.msi' MYPROP='My Value'
Running this from the local command prompt on the server works fine.
msiexec /qn /i "C:\setups\My Software.msi" MYPROP="My Value"
回答1:
If you're calling this from cmd.exe, you'll have to escape the double quotes according to CMD's rules.
powershell.exe -command "echo \"hello world\""
Output
hello world
Personally, I would recommend avoiding passing the parameters in from the command line if at all possible. Maybe you could store the parameter values in a file (eg. serialized XML, JSON), and have the PowerShell script read the file?
Better yet, I would suggest doing any work with processes (eg. msiexec.exe
) through the Start-Process
cmdlet. That way, you can build up the value for the -ArgumentList
parameter in a variable, and then be guaranteed that it will get passed through exactly the way you want it, and furthermore, you will not be restricted to the quoting rules of cmd.exe
.
Consider the following:
$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;
回答2:
Or you can encode your command as base64 strings to avoid any special characters from accidentally being interpreted, like encapsulated double quotes.
powershell.exe -EncodedCommand "ZQBjAGgAbwAgACIAaABlAGwAbABvACAAdwBvAHIAbABkACIA"
Result
hello world
ZQBjAGgAbwAgACIAaABlAGwAbABvACAAdwBvAHIAbABkACIA .... is base64 representation of this. See how I didn't need to escape anything.
echo "hello world"
来源:https://stackoverflow.com/questions/20830215/passing-double-quotes-through-powershell-winrm