Question

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"
Was it helpful?

Solution

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;

OTHER TIPS

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"
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top