Iis 当参数有空格时,如何从powershell调用msdeploy?
我尝试从powershell脚本将参数中的空格发送到msdeploy时遇到问题 有许多其他相关的文章,但没有一篇能够解决这个问题。Iis 当参数有空格时,如何从powershell调用msdeploy?,iis,powershell,msdeploy,Iis,Powershell,Msdeploy,我尝试从powershell脚本将参数中的空格发送到msdeploy时遇到问题 有许多其他相关的文章,但没有一篇能够解决这个问题。 类似的SO问题不起作用: PowerShell错误: 另一个不起作用的SO问题: 最简单的例子是,当我把它弄得更复杂时,它成功了,然后又失败了,那就是转储默认的web站点 $msdeploy=“C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe” &$msdeploy-verb:dump-source:a
类似的SO问题不起作用:
PowerShell错误:
另一个不起作用的SO问题: 最简单的例子是,当我把它弄得更复杂时,它成功了,然后又失败了,那就是转储默认的web站点 $msdeploy=“C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe”
&$msdeploy-verb:dump-source:appHostConfig=`default网站`'-verbose
==成功 这个 $sitename=“默认网站”
&$msdeploy-verb:dump-source:appHostConfig=$sitename-verbose
==失败,出现以下错误
msdeploy.exe:错误:无法识别的参数“”-source:“appHostConfig=default”。所有参数必须以“-”开头。
在C:\xxx\test.ps1:122字符:6
+&
+CategoryInfo:NotSpecified:(错误:未识别…以“-”开头:字符串)[],RemoteException
+FullyQualifiedErrorId:NativeCommandError
错误计数:1。 以下变体也失败了
#失败
$sitename=`'默认网站`'
$sitename=``默认网站`
$sitename=“`'默认网站`”
$sitename=“默认网站”
$sitename=“‘默认网站’” &$msdeploy-verb:dump“-source:appHostConfig=$sitename”-详细
&$msdeploy-verb:dump-source:appHostConfig=“$sitename”-详细
&$msdeploy-verb:dump-source:appHostConfig='$sitename'-verbose
&$msdeploy-verb:dump-source:appHostConfig=`$sitename`'-verbose
&$msdeploy-verb:dump-source:appHostConfig=`“$sitename`”-详细 我不知所措。和我一起工作的每个人都不知所措。说真的,这太糟糕了。我爱地狱。我喜欢msdeploy。我不能说我喜欢把它们放在一起。看起来关注API而不是cli可能更容易 编辑: 皇帝XLII建议的字符串数组中的参数运行良好。下一篇文章介绍了另一种解决方案: 使用您链接到的问题的技术,运行
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>
虽然从您的列表中可以看出,这似乎不适合您
您可以尝试的另一种方法是在数组中建立参数列表,powershell可以自动转义该列表。例如,这将提供与上述相同的输出:
[string[]]$msdeployArgs = @(
"-verb:dump",
"-source:appHostConfig=$sitename",
"-verbose"
)
echoargs $msdeployArgs
我们曾经面临过类似的问题。我们的解决方案如下所示
$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-is escape sequence/character我尝试了各种技术,这是唯一一种对我有效的技术(使用PowerShell 2)
下面是从下面的输入导出的另一种方法
$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位于其默认安装文件夹(包含空格)中的要求。因此,使用转义字符(`)进行包装。只需添加另一种方式,以防对任何人都有帮助:
Invoke-Expression "& '[path to msdeploy]\msdeploy.exe' --% -verb:sync -source:contentPath=`'$source`' -dest:contentPath=`'$dest`'"
“--%”是powershell 3的新功能。From:“您只需在命令行中的任意位置添加--%序列(两个破折号和一个百分号),PowerShell将不会尝试解析该行的其余部分。”找到了一个有效的解决方案并轻松修复。 参考:
我使用了上面答案中的一些想法,并提出了以下更简单的函数来完成这件事 请注意,提供MSDeploy的完整路径非常重要,因为在构建代理下运行时,它有时无法识别MSDeploy的路径
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
以上所有这些都不适用于我,这是有效的解决方案:
# 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
这个问题肯定已经存在很长时间了,最近我花了一些时间来解决它。结果对我来说是成功的,所以我将把它贴在这里,希望它能帮助其他人在将来发现这个问题 要解决的第一个问题是清除msdeploy路径中的空格。这里有两种方法。一个是持久性的,需要您具有服务器访问权限,另一个是PowerShell脚本上下文中的临时性的。两者都可以,但如果你愿意的话,我更喜欢第一种 对于第一种方法,创建一个连接点。示例脚本:
new-item -Path "c:\MS-WebDeploy" -ItemType Junction -Value "c:/Program Files (x86)/iis/microsoft web deploy v3"
对于第二种方法,创建一个PSDrive(本例中为w)
我在下面使用了三个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
一般来说,您可以通过去掉路径/名称中的空格来帮助自己。有时候,这是做不到的,这应该会帮你度过难关。在你发布解决方案后,我还被指向这篇文章:谢谢你的帮助。请向上投票上面列出的PowerShell参数错误/缺陷。对于那些可能错过它的人(我花了一点时间找到了提到的链接),这里是PowerShell connect错误:与其做疯狂的事情来突出显示您的代码,不如使用4个空格(检查我的编辑)。这是唯一一件最终对我有效的事情。但我认为您在src和des$src=“-source:contentPath=[ESC][ESC][ESC][ESC]”的末尾缺少一个引号,c:\aa aa[ESC][ESC][ESC]”;我还要补充一点,powershell的[Esc]字符是`字符。不是一个单一的报价,而是向后的口音(通常与键盘上的倾斜配对)或考虑使用。
New-PSDrive -Name "w" -PSProvider FileSystem -Root "C:/Program Files (x86)/iis/microsoft web deploy v3"
#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"
$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