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

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

当PowerShell看到一个以string开始的命令时,它只是评估string,也就是说,它通常会回显到屏幕上,例如:

 PS> "Hello World" Hello World 

如果您希望PowerShell将string解释为命令名称,那么使用调用操作符(&),如下所示:

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

之后,您可能只需引用包含空格和/或引号字符的参数/参数对。 当你使用复杂的命令行参数调用这样的EXE文件时,通常有一个工具可以显示PowerShell如何将参数发送到EXE文件。 PowerShell社区扩展有这样一个工具。 它被称为echoargs。 您只需用echoargsreplaceEXE文件 – 将所有参数保留就位,它将向您显示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;> 

事实certificate,我之前努力维护连接string周围的双引号。 显然,这是没有必要的,因为即使cmd.exe将剥离出来。

顺便说一句,closuresPowerShell团队。 他们在向我展示单双引号的具体咒语以获得理想结果方面非常有帮助 – 如果您需要保留内部双引号。 :-)他们也意识到这是一个痛苦的领域,但是他们是受到一个特定问题影响的人数的驱动。 如果这是你的痛苦的领域,那么请投票给这个PowerShell错误提交 。

有关PowerShellparsing的更多信息,请查看我的Effective PowerShell博客系列 – 特别是第10项 – “了解PowerShellparsing模式”

更新4/4/2012:这种情况在PowerShell V3中处理起来要容易得多。 有关详细信息,请参阅此博文 。

只需在.exe名称前添加运算符即可。 这里是一个命令以安静模式安装SQL Server Express:

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

我在命令和参数中都有空格,这对我来说是有效的:

 $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的答案一样,但是如果你dynamic地build立你的命令参数并把它们放在一个variables里,它就会起作用。

见本页: http : //edgylogic.com/blog/powershell-and-external-commands-done-right/

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

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

我能够使用以下方法来获得类似的命令:

 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 

关键是:

  • 围绕源参数使用引号,并删除连接string周围的embedded引号
  • 在构build没有空格的SQL连接string中使用替代键名称。 例如,使用“UID”而不是“User Id”,“Server”而不是“Data Source”,“Trusted_Connection”而不是“Integrated Security”等等。 我只能从连接string中删除所有空格后才能使其工作。

我没有尝试在命令行末尾添加“computername”部分,但是希望这个信息能够帮助读者更好地接近他们期望的结果。

这对我工作:

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

只需将path或连接string放在一个数组项中,然后将其他项分别放在一个数组项中。

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

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

新的V3语言特性引用了PowerShell V3中的新转义string:

从Cmd.exe更轻松地重用命令行

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

为了解决这种情况,我们增加了一种“逃避”命令行parsing的新方法。 如果你使用一个魔术参数 – %,我们停止对命令行的正常parsing并切换到更简单的状态。 我们不匹配引号。 我们不停止分号。 我们不扩展PowerShellvariables。 如果使用Cmd.exe语法(例如%TEMP%),我们会扩展环境variables。 除此之外,直到行尾的参数(或pipe道,如果你是pipe道系统)按原样传递。 这里是一个例子:

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

这对我工作:

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

关键似乎是整个命令用外引号括起来,“&”符号用于指定另一个子命令文件正在执行,然后最后用空格在path/文件名周围转义(双 – 双 – )引号在你想执行的第一个地方。

这也是对MS连接问题的唯一解决方法的完成 – 文件不返回非零返回码和-Command是唯一的select。 但是到现在为止它被认为是一个限制,命令是它不支持空格。 我也更新了这个反馈项目。

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

我尝试了所有的build议,但仍然无法使用包含空格的参数运行msiexec.exe 。 所以我的解决scheme结束了使用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() 

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

 powershell -EncodedCommand "QwA==" 

解码后,你会看到这是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时变成这个:

 QwA== 

这里是如何复制在家里:

 $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 

所以,我遇到了类似的问题,并select这样解决:

  1. 用反引号(`)转义你的引号(“)
  2. 用引号(“)围住你的新表情
  3. 使用调用操作符(&),对新string执行命令invoke-expression

示例解决scheme

&{invoke-expression“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`“”}