How to run an EXE file in PowerShell with parameters with spaces and quotes

977,346

Solution 1

When PowerShell sees a command starting with a string it just evaluates the string, that is, it typically echos it to the screen, for example:

PS> "Hello World"
Hello World

If you want PowerShell to interpret the string as a command name then use the call operator (&) like so:

PS> & 'C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe'

After that you probably only need to quote parameter/argument pairs that contain spaces and/or quotation chars. When you invoke an EXE file like this with complex command line arguments it is usually very helpful to have a tool that will show you how PowerShell sends the arguments to the EXE file. The PowerShell Community Extensions has such a tool. It is called echoargs. You just replace the EXE file with echoargs - leaving all the arguments in place, and it will show you how the EXE file will receive the arguments, for example:

PS> echoargs -verb:sync -source:dbfullsql="Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;" -dest:dbfullsql="Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass

Arg 0 is <-verb:sync>
Arg 1 is <-source:dbfullsql=Data>
Arg 2 is <Source=mysource;Integrated>
Arg 3 is <Security=false;User>
Arg 4 is <ID=sa;Pwd=sapass!;Database=mydb;>
Arg 5 is <-dest:dbfullsql=Data>
Arg 6 is <Source=.\mydestsource;Integrated>
Arg 7 is <Security=false;User>
Arg 8 is <ID=sa;Pwd=sapass!;Database=mydb; computername=10.10.10.10 username=administrator password=adminpass>

Using echoargs you can experiment until you get it right, for example:

PS> echoargs -verb:sync "-source:dbfullsql=Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;"
Arg 0 is <-verb:sync>
Arg 1 is <-source:dbfullsql=Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;>

It turns out I was trying too hard before to maintain the double quotes around the connection string. Apparently that isn't necessary because even cmd.exe will strip those out.

BTW, hats off to the PowerShell team. They were quite helpful in showing me the specific incantation of single & double quotes to get the desired result - if you needed to keep the internal double quotes in place. :-) They also realize this is an area of pain, but they are driven by the number of folks are affected by a particular issue. If this is an area of pain for you, then please vote up this PowerShell bug submission.

For more information on how PowerShell parses, check out my Effective PowerShell blog series - specifically item 10 - "Understanding PowerShell Parsing Modes"

UPDATE 4/4/2012: This situation gets much easier to handle in PowerShell V3. See this blog post for details.

Solution 2

Just add the & operator before the .exe name. Here is a command to install SQL Server Express in silence mode:

$fileExe = "T:\SQLEXPRADV_x64_ENU.exe"
$CONFIGURATIONFILE = "T:\ConfSetupSql2008Express.ini"

& $fileExe  /CONFIGURATIONFILE=$CONFIGURATIONFILE

Solution 3

I had spaces in both command and parameters, and this is what worked for me:

$Command = "E:\X64\Xendesktop Setup\XenDesktopServerSetup.exe"
$Parms = "/COMPONENTS CONTROLLER,DESKTOPSTUDIO,DESKTOPDIRECTOR,LICENSESERVER,STOREFRONT /PASSIVE /NOREBOOT /CONFIGURE_FIREWALL /NOSQL"

$Prms = $Parms.Split(" ")
& "$Command" $Prms

It's basically the same as Akira's answer, but this works if you dynamically build your command parameters and put them in a variable.

Solution 4

There are quite a few methods you can use to do it.

There are other methods like using the Call Operator (&), Invoke-Expression cmdlet etc. But they are considered unsafe. Microsoft recommends using Start-Process.

Method 1

A simple example

Start-Process -NoNewWindow -FilePath "C:\wamp64\bin\mysql\mysql5.7.19\bin\mysql" -ArgumentList "-u root","-proot","-h localhost"

In your case

Start-Process -NoNewWindow -FilePath "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" -ArgumentList "-verb:sync","-source:dbfullsql=`"Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`"","-dest:dbfullsql=`"Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`"","computername=10.10.10.10","username=administrator","password=adminpass"

In this method you separate each and every parameter in the ArgumentList using commas.

Method 2

Simple Example

Start-Process -NoNewWindow -FilePath "C:\wamp64\bin\mysql\mysql5.7.19\bin\mysql" -ArgumentList "-u root -proot -h localhost"

In your case

Start-Process -NoNewWindow -FilePath "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" -ArgumentList "-verb:sync -source:dbfullsql=`"Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`" -dest:dbfullsql=`"Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`",computername=10.10.10.10,username=administrator,password=adminpass"

This method is easier as it allows to type your parameters in one go.

Note that in powershell to represent the quotation mark ( " ) in a string you should insert the grave accent ( ` ) (This is the key above the Tab key in the US keyboard).

-NoNewWindow parameter is used to display the new process in the current console window. By default Windows PowerShell opens a new window.

References : Powershell/Scripting/Start-Process

Solution 5

This worked for me:

& 'D:\Server\PSTools\PsExec.exe' @('\\1.1.1.1', '-accepteula', '-d', '-i', $id, '-h', '-u', 'domain\user', '-p', 'password', '-w', 'C:\path\to\the\app', 'java', '-jar', 'app.jar')

Just put paths or connection strings in one array item and split the other things in one array item each.

There are a lot of other options here: https://social.technet.microsoft.com/wiki/contents/articles/7703.powershell-running-executables.aspx

Microsoft should make this way simpler and compatible with command prompt syntax.

Share:
977,346
Admin
Author by

Admin

Updated on February 12, 2022

Comments

  • Admin
    Admin about 2 years

    How do you run the following command in PowerShell?

    C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe -verb:sync -source:dbfullsql="Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;" -dest:dbfullsql="Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass"

  • Admin
    Admin over 14 years
    if using as second example, i get this error: Error: Unrecognized argument '"-source:dbfullsql="""Data'. All arguments must begin with "-".
  • Tyler Collier
    Tyler Collier about 13 years
    I'm sorry, I don't understand. I see that, currently, 6 people have upvoted the answer so I am missing something obvious, but what is the actual answer? Is there a special rule to know about parameters with spaces with PowerShell, or are you just suggesting to take it case-by-case, using EchoArgs to help?
  • Keith Hill
    Keith Hill about 13 years
    Quoting the arguments is usually sufficient but not always. In those cases where it doesn't work, using echoargs gives an indication of how PowerShell is interpreting the arguments before it passes them onto the EXE.
  • Sentient
    Sentient about 12 years
    I tried all other answers, but this was the only answer that worked for me! Thanks for providing this alternative path.
  • Joe Zim
    Joe Zim almost 10 years
    Do you know how I would do this in a .bat file? I'm trying & 'C:\Program Files\Sublime Text 3\sublime_text.exe' directly in the console and it's working, but in a batch file I get an error saying '& was unexpected at this time.'
  • Joe Zim
    Joe Zim almost 10 years
    Nevermind. Found it: START C:\"Program Files"\"Sublime Text 3"\sublime_text.exe
  • Vinoth
    Vinoth about 9 years
    @Keith Hill, This tool amassing. you saved my life. Thank you so much.
  • AnneTheAgile
    AnneTheAgile almost 9 years
    imho this is the best! no base64, no strange --% syntax which toggles substitution, normal powershell substitution rules, no confusion, very readable.
  • BrainSlugs83
    BrainSlugs83 almost 8 years
    This doesn't work. If your parameter has a path name in it, the path name will be divided into multiple parameters.
  • leinad13
    leinad13 almost 8 years
    This is unrelated to the ops question, he specifically asked how to run the long command in his post in powershell. Not how to run a powershell script with spaces in the file path.
  • Tony Wall
    Tony Wall almost 8 years
    Read the title of the question, spaces are the issue not length. This is one valid answer to such problems so worthwhile sharing. Did you have the same problem and actually try it? If you want to improve it submit an edit which includes the actual command in the question and I will accept it.
  • Akira Yamamoto
    Akira Yamamoto almost 7 years
    Nice answer. However, will it work with quotes in the parameters?
  • Carl Walsh
    Carl Walsh almost 6 years
    Chrome labels pscx.codeplex.com as containing harmful programs :\ Is github.com/Pscx/Pscx the right link?
  • jpmc26
    jpmc26 over 5 years
    As Codeplex is read only now, it would be good to update that link.
  • Jean-Daniel Gasser
    Jean-Daniel Gasser over 5 years
    This should be the answer for that question, it's what we are looking for when we search with "Start EXE from PowerShell" keywords. Thank you !
  • Jon Barker
    Jon Barker about 5 years
    Array is definitely the best option - this worked great for me. Except I passed an array variable because my arguments were dynamic. Thanks.
  • Jeremy Thompson
    Jeremy Thompson about 5 years
    Please try this, after everything else this actually worked. And also use the Powershell Extension EchoArgs
  • Mike Casas
    Mike Casas almost 5 years
    Simple always wins! Thanks.
  • SereneWizard
    SereneWizard almost 5 years
    How about running with arguments?
  • Darkgaze
    Darkgaze over 4 years
    @SereneWizard Well, add them after .exe with a space inbetween. Example: .\file.exe param1 param2 param3
  • Vasin Yuriy
    Vasin Yuriy over 4 years
    IMHO best solution
  • Paolo
    Paolo over 4 years
    Thanks for the final note on escaping the quotation mark!
  • Snowcrash
    Snowcrash about 4 years
    Crazy. Who dreamt up the call operator?! The amount of time I've wasted trying to get an exe to run was insane. Is it a CrippleShell-only feature?
  • Snowcrash
    Snowcrash about 4 years
    And why can't you make the Powershell window wider by dragging it?!
  • Binarus
    Binarus over 3 years
    This will fail as soon as there are spaces in the command's name. Then you have to wrap the command in quotes. Then it will be considered just a string by Powershell, and will just be output, instead of the command being started, which brings us back to the OP's problem.
  • Binarus
    Binarus over 3 years
    This will fail as soon as there are spaces in the command's name. Then you have to wrap the command in quotes. Then it will be considered just a string by Powershell, and will just be output, instead of the command being started, which brings us back to the OP's problem.
  • CrazyPyro
    CrazyPyro over 3 years
    The .Split(" ") was the key part of this answer that made it work for me
  • BitQuestions
    BitQuestions about 3 years
    this one should be considered the correct answer.
  • ptr2n0
    ptr2n0 about 2 years
    Do not read from StandardOutput with ReadToEnd() after you wait for exit. It creates a deadlock. Put it before the method "WaitForExit()" See: Microsoft Docs - Diagnostic.Process Class
  • Daniel Lidström
    Daniel Lidström about 2 years
    @ptr2n0 thanks, fixed!