当参数有空格时,如何从powershell调用msdeploy?

时间:2010-08-17 06:00:49

标签: iis powershell msdeploy

我在参数中遇到空格问题,我尝试从powershell脚本发送到msdeploy。

还有许多其他相关文章,但都没有解决问题。
Problems Using Power Shell And MSDeploy.
类似的SO问题不起作用:How to run exe in powershell with parameters with spaces and quotes
PowerShell BUG: Executing commands which require quotes and variables is practically impossible
另一个不起作用的SO问题:Passing parameters in PowerShell 2.0

当我使其变得更复杂时,成功然后失败的最简单的例子就是转储默认网站。

$ msdeploy =“C:\ Program Files \ IIS \ Microsoft Web Deploy \ msdeploy.exe”
&$; $ msdeploy -verb:dump -source:appHostConfig =`'默认网站''-verbose
== SUCCESS

这一个?

$ sitename =“默认网站”
&$; $ msdeploy -verb:dump -source:appHostConfig = $ sitename -verbose
= =失败,出现以下错误
msdeploy.exe:错误:无法识别的参数'“ - source:”appHostConfig = default'。所有参数必须以“ - ”开头。
在C:\ xxx \ test.ps1:122 char:6
+&
+ CategoryInfo:NotSpecified :(错误:无法识别...以“ - ”开头:String)[],RemoteException
+ FullyQualifiedErrorId:NativeCommandError
错误计数:1。

以下变化也失败了
#FAIL
$ sitename =`'默认网站''
$ sitename =`'“默认网站”`'
$ sitename =“`'默认网站''”
$ sitename =“默认网站”
$ sitename =“'默认网站'”

& $ msdeploy -verb:dump“-source:appHostConfig = $ sitename”-verbose
&$; $ msdeploy -verb:dump -source:appHostConfig =“$ sitename”-verbose
&$; $ msdeploy -verb:dump -source:appHostConfig ='$ sitename'-verbose
&$; $ msdeploy -verb:dump -source:appHostConfig =`'$ sitename`'-verbose
&$; $ msdeploy -verb:dump -source:appHostConfig =`“$ sitename`” - verbose

我很茫然。我工作的每个人都不知所措。说真的很糟糕。我喜欢Powershell。我喜欢msdeploy。我不能说我喜欢把它们放在一起。看起来可能更容易关注API而不是cli。

编辑:

Emperor XLII建议的字符串数组中的参数运行良好。以下文章介绍了另一种解决方案:The trials and tribulations of using MSDeploy with PowerShell

function PushToTarget([string]$server, [string]$remotePath, [string]$localPath) {
    cmd.exe /C $("msdeploy.exe -verb:sync -source:contentPath=`"{0}`" -dest:computerName=`"{1}`",contentPath=`"{2}`" -whatif" -f $localPath, $server, $remotePath )
}

9 个答案:

答案 0 :(得分:14)

使用从Keith's answerHow to run exe in powershell with parameters with spaces and quotes的问题,您链接到的问题,运行echoargs -verb:dump -source:appHostConfig=$sitename -verbose给了我这个输出:

Arg 0 is <-verb:dump>
Arg 1 is <-source:appHostConfig=default>
Arg 2 is <web>
Arg 3 is <site>
Arg 4 is <-verbose>

这可以解释appHostConfig=default看到msdeploy的无效论点。

使用echoargs -verb:dump "-source:appHostConfig=$sitename" -verbose运行$sitename = "default web site"似乎会产生所需的参数:

Arg 0 is <-verb:dump>
Arg 1 is <-source:appHostConfig=default web site>
Arg 2 is <-verbose> 

虽然从您的列表中可以看出这对您不起作用。

您可能尝试的另一种方法是在数组中构建参数列表,powershell可以自动转义。例如,它提供与上面相同的输出:

[string[]]$msdeployArgs = @(
  "-verb:dump",
  "-source:appHostConfig=$sitename",
  "-verbose"
)
echoargs $msdeployArgs

答案 1 :(得分:10)

只是添加另一种方式,以防对任何人有帮助:

Invoke-Expression "& '[path to msdeploy]\msdeploy.exe' --% -verb:sync -source:contentPath=`'$source`' -dest:contentPath=`'$dest`'"

&#34; - %&#34;对于powershell 3来说是新手。来自here:&#34;您只需在命令行的任何位置添加 - %序列(两个破折号和百分号),PowerShell不会尝试解析其余部分。线&#34;

答案 2 :(得分:6)

我们遇到了类似的问题。我们的修复如下,

$path = "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe";

$verb = "-verb:sync";

$src = "-source:contentPath=[ESC][ESC][ESC]"c:\aa aa[ESC][ESC][ESC]";

$dest = "-dest:contentPath=[ESC][ESC][ESC]"c:\aa[ESC][ESC][ESC]";

Invoke-Expression "&'$path' $verb $src $dest"; 

其中, ESC - 是转义序列/字符

答案 3 :(得分:6)

找到一个有效的解决方案。 参考:http://answered.site/all-arguments-must-begin-with--at-cwindowsdtldownloadswebserviceswebservicesidservicepublishedwebsitesidservicedeploymentidservicewsdeployps123/4231580/

$msdeploy = "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe"
$msdeployArgs = @(
"-verb:sync",
"-source:iisApp='Default Web Site/HelloWorld'",
"-verbose",
"-dest:archiveDir='c:\temp1'"
)
Start-Process $msdeploy -NoNewWindow -ArgumentList $msdeployArgs

答案 4 :(得分:3)

我在阳光下尝试了所有技术,这是唯一适合我的技术(使用PowerShell 2)。

cmd.exe /C $("msdeploy.exe -verb:sync -source:package=`"{0}`" -dest:auto,IncludeAcls=`"False`" -disableLink:AppPoolExtension -disableLink:ContentExtension -disableLink:CertificateExtension -setParamFile:`"{1}`"" -f $mypackagepath, $myparamfilepath )

答案 5 :(得分:1)

以下是从下面的输入中得出的另一种方法。

$msdeploy = "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe";

$command = "-verb:sync";

$sourcePath = "C:\aa aa\";
$source = $("-source:contentPath=`"{0}`"" -f $sourcePath);

$destPath = "C:\aa"
$destination = $("-dest:contentPath=`"{0}`" -f $destPath);

$msdeploycommand = $("`"{0}`" {1} {2} {3} -verbose" -f $msdeploy, $command, $source, $destination);

cmd.exe /C "`"$msdeploycommand`"";

这适用于MSDeploy.exe在其默认安装文件夹中,该文件夹包含空格。因此使用转义字符(`)包装。

答案 6 :(得分:0)

我已经从上面的答案中使用了一些想法,并提出了以下更简单的功能来做这件事。

请注意,提供MSDeploy的完整路径非常重要,因为在构建代理程序下运行时,它有时无法识别msrploy的PATH。

function Deploy([string]$server, [string]$remotePath, [string]$localPath) {
        $msdeploy = "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe";
        cmd.exe /C $("`"{3}`" -verb:sync -source:contentPath=`"{0}`" -dest:computerName=`"{1}`",contentPath=`"{2}`" " -f $localPath, $server, $remotePath , $msdeploy )
    }

用法

Deploy $hostName $remotePath $source

答案 7 :(得分:0)

以上所有内容对我都不起作用,这是有效的解决方案:

# get msdeploy exe
$MSDeploy = ${env:ProgramFiles}, ${env:ProgramFiles(x86)} |
        ForEach-Object {Get-ChildItem -Path $_ -Filter 'MSDeploy.exe' -Recurse} |
        Sort-Object -Property @{Expression={[version]$_.VersionInfo.FileVersion}} -Descending |
        Select-Object -First 1 -ExpandProperty FullName

#build deploy command        
$deplyCmd = """""$MSDeploy"" -verb:sync -dest:iisApp=""Default Web Site"" -enableRule:DoNotDeleteRule -source:iisApp=""$ExtraWebFilesFolder"""    

#execute    
&cmd /c $deplyCmd

答案 8 :(得分:0)

这个问题肯定存在很长时间了,最​​近我花了一些时间来解决它。结果对我来说是成功的,所以我将其发布在这里,希望它能对以后找到这个问题的其他人有所帮助。

要解决的第一个问题是摆脱msdeploy路径中的空格。这里有两种方法。一种是持久性的,需要您具有服务器访问权限,另一种是在PowerShell脚本的上下文中是临时的。两种都可以,但是如果您可以选择的话,我更喜欢第一个。

对于第一种方法,创建一个接合点。示例脚本:

new-item -Path "c:\MS-WebDeploy" -ItemType Junction -Value "c:/Program Files (x86)/iis/microsoft web deploy v3"

对于第二种方法,创建一个PSDrive(在此示例中为w)

New-PSDrive -Name "w" -PSProvider FileSystem -Root "C:/Program Files (x86)/iis/microsoft web deploy v3"

我在下面使用三个PowerShell变量。出于示例目的,假设所有三个都有空格。

  • $ ParamFilePath =“ c:\ deployment files \ parameters.xml”
  • $ PackageName =“ c:\ deployment files \ My Website.zip”
  • $ WebAppPath =“默认网站”

首先,创建一个数组并根据需要构建参数。

#nothing needs to be done with these arguments so we'll start with them
[string[]]$arguments = @("-verb:sync", "-dest:auto", "-disableLink:AppPoolExtension", "-disableLink:ContentExtension", "-disableLink:CertificateExtension", "-allowUntrusted")

#double up on the quotes for these paths after the colon
$arguments += "-setParamFile:""$ParamFilePath"""
$arguments += "-source:package=""$PackageName"""

#must not have spaces with the commma, use single quotes on the name and value here
$arguments += "-setParam:name='IIS Web Application Name',value='$WebAppPath'"

#add your own logic for optional arguments  
$arguments += "-EnableRule:EncryptWebConfig"

现在构建msdeploy命令并放置PowerShell换码序列,以防止PowerShell在以后“帮助”。使用您通过联结或PSDrive创建的路径

$command = "w:\msdeploy.exe" + " --% " + $arguments -join " "

最后,将该命令作为脚本块执行。

$sb = $ExecutionContext.InvokeCommand.NewScriptBlock($command) 
& $sb

我已经将它和更多的代码包装到一个脚本中了,就像这样。

.\Run-WebDeploy -WebAppPath "Default Web Site" -PackageName "c:\deployment files\My Website.zip"  -ParamFilePath "c:\deployment files\parameters.xml"  -EncryptWebConfig

通常,通过消除路径/名称中的空格,您可以大有帮助。有时,这是无法完成的,这应该可以帮助您解决问题。