如何在PowerShell中运行以下命令?

C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe -verb:sync -source:dbfullsql="数据源=mysource;集成安全=false;用户ID=sa;Pwd=sapass!;数据库=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 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}>

其他回答

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

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

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

这基本上与Akira的答案相同,但如果您动态地构建命令参数并将它们放入变量中,则可以工作。

这招对我很管用:

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

关键似乎是整个命令都用外引号括起来,“&”&用于指定正在执行的另一个子命令文件,然后最后在路径/文件名周围转义(双-双-)引号,其中有空格。

这也是MS连接问题的唯一解决方案,即-File不传递非零返回码,而-Command是唯一的替代方案。但到目前为止,人们认为-Command的一个限制是它不支持空格。我也更新了反馈内容。

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

另一种答案是使用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

你可以使用很多方法来做到这一点。

还有其他方法,如使用调用操作符(&),Invoke-Expression cmdlet等。但它们被认为是不安全的。微软建议使用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

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

PS> "Hello World"
Hello World

如果你想让PowerShell将字符串解释为命令名,那么使用调用操作符(&),如下所示:

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>

使用回声,你可以不断实验,直到你得到正确的答案,例如:

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也会删除这些文件。

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

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

2012年4月4日更新:这种情况在PowerShell V3中更容易处理。详见这篇博客文章。