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

Van*_*ans 311 parameters quotes powershell 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"

Kei*_*ill 324

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

PS> "Hello World"
Hello World
Run Code Online (Sandbox Code Playgroud)

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

PS> & 'C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe'
Run Code Online (Sandbox Code Playgroud)

之后,您可能只需要引用包含空格和/或引用字符的参数/参数对.当您使用复杂的命令行参数调用这样的EXE文件时,通常会有一个工具向您展示PowerShell如何将参数发送到EXE文件.在PowerShell的社区扩展有这样的工具.它被称为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>
Run Code Online (Sandbox Code Playgroud)

使用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;>
Run Code Online (Sandbox Code Playgroud)

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

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

有关PowerShell如何解析的更多信息,请查看我的Effective PowerShell博客系列 - 特别是第10项 - "了解PowerShell解析模式"

更新2012年4月4日:这种情况在PowerShell V3中更容易处理.有关详细信息,请参阅此博文.

  • 对不起,我不明白.我看到,目前有6个人已经提出了答案,所以我错过了一些明显的东西,但实际答案是什么?是否有一个特殊的规则来了解有关PowerShell空间的参数,或者您只是建议逐个使用EchoArgs来帮助它? (2认同)

小智 59

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

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

& $fileExe  /CONFIGURATIONFILE=$CONFIGURATIONFILE
Run Code Online (Sandbox Code Playgroud)


Mic*_*rob 48

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

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

$Prms = $Parms.Split(" ")
& "$Command" $Prms
Run Code Online (Sandbox Code Playgroud)

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

  • `.Split(" ")` 是这个答案的关键部分,使它对我有用 (3认同)
  • 恕我直言,这是最好的!没有base64,没有奇怪的-%语法,可以切换替换,普通的powershell替换规则,没有混淆,非常易读。 (2认同)
  • 这不起作用。如果你的参数里面有路径名,路径名会被分成多个参数。 (2认同)

Aki*_*oto 21

这对我有用:

& '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')
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • Array 绝对是最好的选择 - 这对我很有用。除了我传递了一个数组变量,因为我的参数是动态的。谢谢。 (2认同)

Bao*_*dad 17

请参阅此页: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:
Run Code Online (Sandbox Code Playgroud)


dar*_*aze 13

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

.....>.\ file.exe

要么

......> full\path\to\file.exe

  • 一旦命令名称中有空格,此操作就会失败。然后你必须将命令用引号引起来。然后它会被Powershell认为只是一个字符串,并且只会被输出,而不是启动命令,这让我们回到了OP的问题。 (7认同)
  • 这应该是该问题的答案,这就是我们使用“从 PowerShell 启动 EXE”关键字搜索时要寻找的内容。谢谢 ! (5认同)
  • @SereneWizard 好吧,将它们添加到 .exe 之后,中间留一个空格。示例:.\file.exe 参数1 参数2 参数3 (3认同)
  • 带参数运行怎么样? (2认同)

Mis*_*oda 12

您可以使用多种方法来执行此操作。

还有其他方法,例如使用呼叫操作符(),Invoke-Expression cmdlet等。但是,它们被认为是不安全的。Microsoft建议使用Start-Process

方法1

一个简单的例子

Start-Process -NoNewWindow -FilePath "C:\wamp64\bin\mysql\mysql5.7.19\bin\mysql" -ArgumentList "-u root","-proot","-h localhost"
Run Code Online (Sandbox Code Playgroud)

就你而言

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"
Run Code Online (Sandbox Code Playgroud)

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

方法2

简单的例子

Start-Process -NoNewWindow -FilePath "C:\wamp64\bin\mysql\mysql5.7.19\bin\mysql" -ArgumentList "-u root -proot -h localhost"
Run Code Online (Sandbox Code Playgroud)

就你而言

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"
Run Code Online (Sandbox Code Playgroud)

此方法更容易,因为它允许一次输入您的参数。

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

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

参考:Powershell /脚本/启动过程

  • 简单总是胜利!谢谢。 (2认同)

小智 12

您可以使用:

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"
Run Code Online (Sandbox Code Playgroud)

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


G-M*_*Mac 9

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

msdeploy.exe -verb=sync "-source=dbFullSql=Server=THESERVER;Database=myDB;UID=sa;Pwd=saPwd" -dest=dbFullSql=c:\temp\test.sql
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

关键点是:

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

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

  • 我尝试了所有其他答案,但这是唯一对我有用的答案!感谢您提供此替代路径。 (2认同)

Loï*_*HEL 6

PowerShell V3中的新转义字符串,引自New V3语言功能:

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

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

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

PS> echoargs.exe --% %USERNAME%,this=$something{weird}
Arg 0 is <jason,this=$something{weird}>
Run Code Online (Sandbox Code Playgroud)


Dan*_*röm 5

我尝试了所有建议,但仍然无法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()
Run Code Online (Sandbox Code Playgroud)


And*_*Rae 5

您可以通过不同方式在 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;
Run Code Online (Sandbox Code Playgroud)

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

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

如果您只想将 winrar 存档文件作为 .exe 文件调用,您还可以使用 invoke-command cmdlet 和静默参数 /S 解压缩它(它将在与压缩的文件夹相同的文件夹中解压)。

> Invoke-Command -ScriptBlock { C:\Your-path\archivefile.exe /S };
Run Code Online (Sandbox Code Playgroud)

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

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


Fel*_*lix 5

我使用这种简单、干净和有效的方法。

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

# 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";
  
Run Code Online (Sandbox Code Playgroud)