这个PowerShell命令行引用/转义是怎么回事?

这个PowerShell命令行引用/转义是怎么回事?,powershell,msdeploy,psake,Powershell,Msdeploy,Psake,我显然不知道我在做什么 我终于让这个PowerShell命令开始工作了。但我不明白为什么它会起作用 我关心的是最后的“”字符: &"C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" ` -verb:sync ` -source:contentPath="$build_directory\deploy" ` -dest:contentPath="$server_temp_directory,com

我显然不知道我在做什么

我终于让这个PowerShell命令开始工作了。但我不明白为什么它会起作用

我关心的是最后的“”字符:

    &"C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" `
    -verb:sync `
    -source:contentPath="$build_directory\deploy" `
    -dest:contentPath="$server_temp_directory,computerName=$server,username=$server_username,password=$server_password" `
    -verbose `
    -postSync=runCommand="powershell -NoLogo -NoProfile -Command $server_temp_directory\remotetasks.ps1 Deploy""
为什么我需要双引号

我的IDE(PowerGUI)说这行没有正确结束,但这是我使命令按需要运行的唯一方法

我和IDE不知道在PowerShell中引用什么


来自echoargs的少量输出:

如果我跑步:

echoargs -postSync=runCommand="powershell -NoLogo -NoProfile -Command $server_temp_directory\remotetasks.ps1 Deploy""
我得到:

Arg 0 is <-postSync=runCommand=powershell -NoLogo -NoProfile -Command \remotetasks.ps1 Deploy>
我已经尝试过这样的阵列解决方案:

$arguments = @("-verb:sync",
               "-source:contentPath=$build_directory\deploy",
               "-dest:contentPath=$server_temp_directory,computerName=$server,username=$server_username,password=$server_password",
               "-verbose",
               "-postSyncOnSuccess:runCommand=powershell -Command $server_temp_directory\remotetasks.ps1 Deploy")
&"C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" $arguments
我仍然得到相同的错误:

错误:无法识别的参数''-postSyncOnSuccess:runCommand=powershell-Command c:\temp\kslog\remotetasks.ps1 Deploy''。所有参数必须以“-”开头


我在这里做错什么了吗?

这是一个臭名昭著的问题。票证“执行需要引号和变量的命令实际上是不可能的”是投票最多的错误:

你也可以找到一些解决办法。但我建议您将所有参数组合为一个数组,并使用
&
操作符使用该数组调用本机命令。请参阅答案和示例: 和

我没有使用
msdeploy.exe
,无法为您的案例提供一些演示代码。但我将这种方法应用到了许多其他棘手的本机命令中,效果非常好。请尝试一下,让我们知道结果


另外,从技术上讲,这并不完全是对您的问题的回答,但我认为您仍在寻找一种切实可行的方法,因此这可能还是有帮助的。

这里的一个问题是PowerShell无法处理基于cmd的msdeploy中表示的“程序文件”之间的空格翻译

这是一个非常基本的解决方案,利用了过时的DOS限制,但可以使用以下非空白引用来代替它们:

\Program Files\ ... \Progra~1\
\Program Files (x86)\ ... \Progra~2\
它是跛脚的,但它是有效的

您还可以创建一个调用cmd并执行命令的函数。本例还假设您试图调用的(msdeploy等)位于路径中

function PushToTarget() {
     cmd.exe /C $("msdeploy.exe -verb:sync -source:apphostconfig=yourwebapp-dev -dest:archivedir=d:\backup")
}

我终于知道怎么做了。下面是一个示例脚本:

$src = 'C:\sandbox\Test Folder\A'
$dest = 'C:\sandbox\Test Folder\B'
$msdeploy = Get-Command 'C:\Program Files (x86)\IIS\Microsoft Web Deploy V3\msdeploy.exe'
$command = "& `$msdeploy --% -verb:sync -source:contentPath=""$src"" -dest:contentPath=""$dest"""
$sb = $ExecutionContext.InvokeCommand.NewScriptBlock($command)
& $sb

谢谢你的回答!这个周末我不在代码区,但我会在周一回来时尝试你的建议。你是对的,从技术上来说,这并不能解释为什么双qoutes有效。。。但是,如果它是一个bug,而不是设计的,那么可能不值得深入了解。我很快就回来。我尝试了各种组合,使用数组作为参数。似乎什么都不管用。你知道为什么吗?我不使用msdeploy.exe,自己也不能尝试。现在,您可以用两个额外的转义引号尝试最后一个参数:“-postSyncOnSuccess:runCommand=“powershell-Command$server\u temp\u directory\remotetasks.ps1 Deploy”“(用于反勾号,以避免格式化)感谢您的建议!不幸的是,这没有什么区别。我仍然收到相同的错误消息。事实上,它确实有一点不同:当使用转义的qoute标记时,echoargs命令返回8个参数,而不使用它时,实际上只返回5个参数。它们在执行时都不起作用,但不同之处在于。。。看这里,我们在2013年,powershell和msdeploy仍然无法应对。我也遇到了同样的问题,在做了很多事情之后,我最终从批处理文件中调用了msdeploy.exe(这有点违背了powershell的用途)。我希望史密斯女士能解决这个问题。
function PushToTarget() {
     cmd.exe /C $("msdeploy.exe -verb:sync -source:apphostconfig=yourwebapp-dev -dest:archivedir=d:\backup")
}
$src = 'C:\sandbox\Test Folder\A'
$dest = 'C:\sandbox\Test Folder\B'
$msdeploy = Get-Command 'C:\Program Files (x86)\IIS\Microsoft Web Deploy V3\msdeploy.exe'
$command = "& `$msdeploy --% -verb:sync -source:contentPath=""$src"" -dest:contentPath=""$dest"""
$sb = $ExecutionContext.InvokeCommand.NewScriptBlock($command)
& $sb