如何使用带空格和引号的参数在PowerShell中运行EXE文件

时间:2009-11-04 14:10:04

标签: powershell parameters quotes exe spaces

如何在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“

19 个答案:

答案 0 :(得分:297)

当PowerShell看到以字符串开头的命令时,它只是评估字符串,也就是说,它通常会将其回显到屏幕上,例如:

PS> "Hello World"
Hello World

如果您希望PowerShell将字符串解释为命令名,请使用调用运算符(&),如下所示:

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

之后,您可能只需要引用包含空格和/或引号字符的参数/参数对。当您使用复杂的命令行参数调用这样的EXE文件时,通常会有一个工具向您展示PowerShell如何将参数发送到EXE文件。 PowerShell Community Extensions有这样的工具。它被称为echoargs。您只需用echoargs替换EXE文件 - 保留所有参数,它将显示EXE文件将如何接收参数,例如:

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>

使用echoargs,您可以进行实验,直到您做对,例如:

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;>

事实证明我之前为了维护连接字符串周围的双引号而过于努力。显然这不是必要的,因为即使cmd.exe也会删除它们。

BTW,对PowerShell团队说。他们非常乐于向我展示单身和单身的具体咒语。双引号以获得所需的结果 - 如果您需要保持内部双引号到位。 :-)他们也意识到这是一个痛苦的领域,但他们是由受特定问题影响的人数驱动的。如果这对您来说是一个痛苦的领域,那么请将此PowerShell bug submission投票。

有关PowerShell如何解析的详细信息,请查看我的Effective PowerShell blog series - 具体为item 10 - "Understanding PowerShell Parsing Modes"

更新2012年4月4日:在PowerShell V3中,这种情况变得更容易处理。请参阅此blog post for details

答案 1 :(得分:51)

只需在.exe名称前添加&amp; 运算符即可。 以下是以静默方式安装SQL Server Express的命令:

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

& $fileExe  /CONFIGURATIONFILE=$CONFIGURATIONFILE

答案 2 :(得分:41)

我在命令和参数中都有空格,这对我有用:

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

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

它与Akira的答案基本相同,但是如果您动态构建命令参数并将它们放在变量中,则此方法有效。

答案 3 :(得分:17)

这对我有用:

& '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')

只需将路径或连接字符串放在一个数组项中,并将其他内容分别放在一个数组项中。

此处还有很多其他选项:https://social.technet.microsoft.com/wiki/contents/articles/7703.powershell-running-executables.aspx

Microsoft应该使这种方式更简单并与命令提示符语法兼容。

答案 4 :(得分:12)

查看此页面: https://slai.github.io/posts/powershell-and-external-commands-done-right/

使用vshadow作为外部可执行文件的摘要:

$exe = "H:\backup\scripts\vshadow.exe"
&$exe -p -script=H:\backup\scripts\vss.cmd E: M: P:

答案 5 :(得分:11)

如果有人想知道如何运行可执行文件:

.....&gt; \的file.exe

...&GT;全\路径\到\的file.exe

答案 6 :(得分:8)

我能够使用以下方法使我的类似命令工作:

msdeploy.exe -verb=sync "-source=dbFullSql=Server=THESERVER;Database=myDB;UID=sa;Pwd=saPwd" -dest=dbFullSql=c:\temp\test.sql

对于你的命令(现在不是很有帮助),事情看起来像这样:

msdeploy.exe -verb=sync "-source=dbfullsql=Server=mysource;Trusted_Connection=false;UID=sa;Pwd=sapass!;Database=mydb;" "-dest=dbfullsql=Server=mydestsource;Trusted_Connection=false;UID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass

关键点是:

  • 在source参数周围使用引号,并删除连接字符串周围的嵌入式引号
  • 在构建没有空格的SQL连接字符串时使用备用键名。例如,使用“UID”而不是“User Id”,“Server”而不是“Data Source”,“Trusted_Connection”而不是“Integrated Security”,等等。一旦我从连接字符串中删除了所有空格,我才能使它工作。

我没有尝试在命令行的末尾添加“computername”部分,但希望此信息可以帮助其他人阅读此内容,使其更接近他们想要的结果。

答案 7 :(得分:6)

PowerShell V3中的新转义字符串,引自 New V3 Language Features

  

从Cmd.exe轻松重用命令行

Web上充满了为Cmd.exe编写的命令行。这些命令行在PowerShell中经常运行,但是当它们包含某些字符(例如,分号(;),美元符号($)或花括号)时,您必须进行一些更改,可能会添加一些引号。这似乎是许多轻微头痛的根源。

为了帮助解决这个问题,我们添加了一种“逃避”解析命令行的新方法。如果你使用魔术参数 - %,我们停止正常解析你的命令行并切换到更简单的东西。我们不匹配报价。我们不会以分号停止。我们不会扩展PowerShell变量。如果您使用Cmd.exe语法(例如%TEMP%),我们会扩展环境变量。除此之外,直到行尾(或管道,如果你是管道)的参数按原样传递。这是一个例子:

PS> echoargs.exe --% %USERNAME%,this=$something{weird}
Arg 0 is <jason,this=$something{weird}>

答案 8 :(得分:6)

您可以使用很多方法来实现它。

  

还有其他方法,例如使用呼叫操作员(&amp; ),调用表达式 cmdlet等。但它们被视为不安全。 Microsoft建议使用 Start-Process

方法1

一个简单的例子

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

在你的情况下

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"

在此方法中,您可以使用逗号分隔ArgumentList中的每个参数。

方法2

简单示例

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

在你的情况下

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"

这种方法更容易,因为它允许一次输入参数。

  

请注意,在powershell中表示字符串中的引号(“),您应该插入严重重音(`)(这是Tab键上方的键)在美国键盘)。

     

<强> -NoNewWindow   参数用于在当前控制台窗口中显示新进程。默认情况下,Windows PowerShell会打开一个新窗口。

参考文献:Powershell/Scripting/Start-Process

答案 9 :(得分:4)

我尝试了所有建议,但仍然无法使用包含空格的参数运行msiexec.exe。所以我的解决方案最终使用System.Diagnostics.ProcessStartInfo

# can have spaces here, no problems
$settings = @{
  CONNECTION_STRING = "... ..."
  ENTITY_CONTEXT = "... ..."
  URL = "..."
}

$settingsJoined = ($settings.Keys | % { "$_=""$($settings[$_])""" }) -join " "
$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.WorkingDirectory = $ScriptDirectory
$pinfo.FileName = "msiexec.exe"
$pinfo.RedirectStandardError = $true
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$pinfo.Arguments = "/l* install.log /i installer.msi $settingsJoined"
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$p.WaitForExit()
$stdout = $p.StandardOutput.ReadToEnd()

答案 10 :(得分:3)

另一个答案是使用Base64编码的命令开关:

powershell -EncodedCommand "QwA6AFwAUAByAG8AZwByAGEAbQAgAEYAaQBsAGUAcwBcAEkASQBTAFwATQBpAGMAcgBvAHMAbwBmAHQAIABXAGUAYgAgAEQAZQBwAGwAbwB5AFwAbQBzAGQAZQBwAGwAbwB5AC4AZQB4AGUAIAAtAHYAZQByAGIAOgBzAHkAbgBjACAALQBzAG8AdQByAGMAZQA6AGQAYgBmAHUAbABsAHMAcQBsAD0AIgBEAGEAdABhACAAUwBvAHUAcgBjAGUAPQBtAHkAcwBvAHUAcgBjAGUAOwBJAG4AdABlAGcAcgBhAHQAZQBkACAAUwBlAGMAdQByAGkAdAB5AD0AZgBhAGwAcwBlADsAVQBzAGUAcgAgAEkARAA9AHMAYQA7AFAAdwBkAD0AcwBhAHAAYQBzAHMAIQA7AEQAYQB0AGEAYgBhAHMAZQA9AG0AeQBkAGIAOwAiACAALQBkAGUAcwB0ADoAZABiAGYAdQBsAGwAcwBxAGwAPQAiAEQAYQB0AGEAIABTAG8AdQByAGMAZQA9AC4AXABtAHkAZABlAHMAdABzAG8AdQByAGMAZQA7AEkAbgB0AGUAZwByAGEAdABlAGQAIABTAGUAYwB1AHIAaQB0AHkAPQBmAGEAbABzAGUAOwBVAHMAZQByACAASQBEAD0AcwBhADsAUAB3AGQAPQBzAGEAcABhAHMAcwAhADsARABhAHQAYQBiAGEAcwBlAD0AbQB5AGQAYgA7ACIALABjAG8AbQBwAHUAdABlAHIAbgBhAG0AZQA9ADEAMAAuADEAMAAuADEAMAAuADEAMAAsAHUAcwBlAHIAbgBhAG0AZQA9AGEAZABtAGkAbgBpAHMAdAByAGEAdABvAHIALABwAGEAcwBzAHcAbwByAGQAPQBhAGQAbQBpAG4AcABhAHMAcwAiAA=="

解码后,您会看到OP的原始片段包含所有参数和双引号。

powershell.exe -EncodedCommand

Accepts a base-64-encoded string version of a command. Use this parameter
to submit commands to Windows PowerShell that require complex quotation
marks or curly braces.

原始命令:

 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"

当编码为Base64时会变成这个:

QwA6AFwAUAByAG8AZwByAGEAbQAgAEYAaQBsAGUAcwBcAEkASQBTAFwATQBpAGMAcgBvAHMAbwBmAHQAIABXAGUAYgAgAEQAZQBwAGwAbwB5AFwAbQBzAGQAZQBwAGwAbwB5AC4AZQB4AGUAIAAtAHYAZQByAGIAOgBzAHkAbgBjACAALQBzAG8AdQByAGMAZQA6AGQAYgBmAHUAbABsAHMAcQBsAD0AIgBEAGEAdABhACAAUwBvAHUAcgBjAGUAPQBtAHkAcwBvAHUAcgBjAGUAOwBJAG4AdABlAGcAcgBhAHQAZQBkACAAUwBlAGMAdQByAGkAdAB5AD0AZgBhAGwAcwBlADsAVQBzAGUAcgAgAEkARAA9AHMAYQA7AFAAdwBkAD0AcwBhAHAAYQBzAHMAIQA7AEQAYQB0AGEAYgBhAHMAZQA9AG0AeQBkAGIAOwAiACAALQBkAGUAcwB0ADoAZABiAGYAdQBsAGwAcwBxAGwAPQAiAEQAYQB0AGEAIABTAG8AdQByAGMAZQA9AC4AXABtAHkAZABlAHMAdABzAG8AdQByAGMAZQA7AEkAbgB0AGUAZwByAGEAdABlAGQAIABTAGUAYwB1AHIAaQB0AHkAPQBmAGEAbABzAGUAOwBVAHMAZQByACAASQBEAD0AcwBhADsAUAB3AGQAPQBzAGEAcABhAHMAcwAhADsARABhAHQAYQBiAGEAcwBlAD0AbQB5AGQAYgA7ACIALABjAG8AbQBwAHUAdABlAHIAbgBhAG0AZQA9ADEAMAAuADEAMAAuADEAMAAuADEAMAAsAHUAcwBlAHIAbgBhAG0AZQA9AGEAZABtAGkAbgBpAHMAdAByAGEAdABvAHIALABwAGEAcwBzAHcAbwByAGQAPQBhAGQAbQBpAG4AcABhAHMAcwAiAA==

以下是如何在家复制:

$command = '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"'
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encodedCommand = [Convert]::ToBase64String($bytes)
$encodedCommand

#  The clip below copies the base64 string to your clipboard for right click and paste.
$encodedCommand | Clip

答案 11 :(得分:3)

这对我有用:

PowerShell.exe -Command "& ""C:\Some Script\Path With Spaces.ps1"""

关键似乎是整个命令都包含在外部引号中,&#34;&amp;&#34; &符号用于指定正在执行的另一个子命令文件,然后最终在路径/文件名周围转义(doubled-double-)引号,并在第一个位置执行空格。

这也完成了MS连接问题的唯一解决方法 - 文件不传递非零返回码,而-Command是唯一的选择。但到目前为止,人们认为-Command的局限在于它不支持空间。我也更新了反馈项目。

http://connect.microsoft.com/PowerShell/feedback/details/750653/powershell-exe-doesn-t-return-correct-exit-codes-when-using-the-file-option

答案 12 :(得分:3)

您可以通过PowerShell以不同的方式运行exe文件。例如,如果您想运行unrar.exe并提取.rar文件,您只需在powershell中写下:

$extract_path = "C:\Program Files\Containing folder";
$rar_to_extract = "C:\Path_to_arch\file.rar"; #(or.exe if its a big file)  
C:\Path_here\Unrar.exe x -o+ -c- $rar_to_extract $extract_path;

但有时,这不起作用所以你必须使用&amp;参数如上图所示: 例如,使用vboxmanage.exe(管理虚拟机虚拟机的工具),您必须像这样调用字符串之外的参数,不带引号:

> $vmname = "misae_unrtes_1234123"; #(name too long, we want to change this)
> & 'C:\Program Files\Oracle\VirtualBox\VBoxManage.exe' modifyvm $vmname --name UBUNTU;

如果您只想将winrar归档文件称为.exe文件,您还可以使用invoke-command cmdlet和Silent参数/ S解压缩它(它将在与其相同的文件夹中提取自身)压缩)。

> Invoke-Command -ScriptBlock { C:\Your-path\archivefile.exe /S };

因此有几种方法可以在powershell中运行带有参数的.exe文件。

有时,必须找到一种解决方法才能使其正常工作,这可能需要一些进一步的努力和痛苦:),具体取决于.exe的编译方式或创建者的方式。

答案 13 :(得分:2)

您可以使用:

Start-Process -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"

根据帮助指南,此处要注意的关键是FilePath必须位于位置0。要调用Commandlet的帮助指南,只需输入Get-Help <Commandlet-name> -Detailed即可。在这种情况下,它是Get-Help Start-Process -Detailed

答案 14 :(得分:1)

我在笔记本电脑上可以正常运行以下代码:

& $msdeploy `
-source:package="$publishFile" `
-dest:auto,computerName="$server",includeAcls="False",UserName="$username",Password="$password",AuthType="$auth" `
-allowUntrusted  `
-verb:sync  `
-enableRule:DoNotDeleteRule `
-disableLink:AppPoolExtension  `
-disableLink:ContentExtension  `
-disableLink:CertificateExtension  `
-skip:objectName=filePath,absolutePath="^(.*Web\.config|.*Environment\.config)$" `
-setParam:name=`"IIS Web Application Name`",value="$appName"

然后,当我尝试直接在一台服务器上运行该命令时,我开始遇到这些错误"Unrecognized argument ...etc.... All arguments must begin with "-". "

尝试了所有可能的解决方法(没有成功)后,我发现服务器(Windows 2008 R2)上的Powershell是3.0版,而我的笔记本电脑是5.0版。 (您可以使用“ $ PSVersionTable”查看版本)。

upgrading Powershell更新到最新版本后,它又开始工作。

答案 15 :(得分:0)

所以,我遇到了类似的问题并选择以这种方式解决它:

  1. 使用反引号(`)
  2. 来逃避您的引号(&#34;)字符
  3. 用引号(&#34;)
  4. 围绕您的新表达
  5. 使用呼叫运算符(&amp;),在新字符串
  6. 上发出命令invoke-expression

    示例解决方案:

      

    &安培; {invoke-expression&#34; C:\ Program Files \ IIS \ Microsoft Web Deploy \ msdeploy.exe -verb:sync -source:dbfullsql =`&#34; Data Source = mysource; Integrated Security = false; User ID = SA; PWD = sapass;!数据库= MYDB;`&#34; -dest:dbfullsql =`&#34; Data Source =。\ mydestsource; Integrated Security = false; User ID = sa; Pwd = sapass !; Database = mydb;`&#34;,computername = 10.10.10.10,username =管理员,密码= adminpass`&#34;&#34; }

答案 16 :(得分:0)

对于可执行文件名称,可以使用 new-alias cmdlet避免处理空格或需要将可执行文件添加到$ PATH环境中。

PS> new-alias msdeploy "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe"
PS> msdeploy ...

要列出或修改PS别名,请参见

PS> get-alias
PS> set-alias

来自Jeffery Hicks Aarticle

其他答案解决了论点。

答案 17 :(得分:0)

我使用这种简单,干净而有效的方法。

我将参数放在数组中,每行1个。这样,很容易阅读和编辑。 然后,我使用一个简单的技巧将双引号内的所有参数传递给具有1个单参数的函数。这将它们(包括数组)展平为单个字符串,然后我使用PS的“ Invoke-Expression”执行该字符串。该伪指令专门用于将字符串转换为可运行命令。 效果很好:

                    # function with one argument will flatten 
                    # all passed-in entries into 1 single string line
Function Execute($command) {
                    # execute:
    Invoke-Expression $command;
                    # if you have trouble try:
  # Invoke-Expression "& $command";
                    # or if you need also output to a variable
  # Invoke-Expression $command | Tee-Object -Variable cmdOutput;

}

#  ... your main code here ...

               # The name of your executable app
$app = 'my_app.exe';
               # List of arguments:
               #    Notice the type of quotes - important !
               #    Those in single quotes are normal strings, like 'Peter'
$args = 'arg1',
        'arg2',
        $some_variable,
        'arg4',
        "arg5='with quotes'",
        'arg6',
        "arg7 \ with \ $other_variable",
        'etc...';

               # pass all arguments inside double quotes
Execute "$app $args";

答案 18 :(得分:0)

Cmd可以处理运行带引号的exe,但是Powershell不能。因为我没有EXE,所以我将只处理EXE本身的运行。如果您确实需要在外部命令的参数中发送双引号,那么这是另一个在其他地方讨论过的问题。

1)反引号:

C:\Program` Files\IIS\Microsoft` Web` Deploy\msdeploy.exe

2)将exe文件夹添加到您的路径中,也许在您的$ profile中

$env:path += ';C:\Program Files\IIS\Microsoft Web Deploy\'
msdeploy