PowerShellスクリプトからmsdeployに送信しようとしているパラメーターのスペースに問題が発生しています。
他にも多くの関連記事がありますが、どれも問題を解決していません。
Power ShellとMSDeployの使用に関する問題
同様のSO機能しない問題: スペースと引用符を含むパラメーターを使用してPowerShellでexeを実行する方法
PowerShellのバグ:引用符と変数を必要とするコマンドを実行することは事実上不可能です
別のSO機能しない問題: PowerShell 2.0でパラメーターを渡す
成功してから複雑にすると失敗する最も単純な例は、デフォルトのWebサイトをダンプすることです。
$ msdeploy = "C:\ Program Files\IIS\Microsoft Web Deploy\msdeploy.exe"
&$ msdeploy -verb:dump -source:appHostConfig = `'デフォルトのWebサイト`' -verbose
==成功
これです?
$ sitename = "デフォルトのWebサイト"
&$ 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。
次のバリエーションも失敗しました
#不合格
$ sitename = `'デフォルトのWebサイト`'
$ sitename = `'"デフォルトのWebサイト "`'
$ sitename = "` 'デフォルトのウェブサイト `'"
$ sitename = "デフォルトのWebサイト"
$ sitename = "'デフォルトのWebサイト'"
&$ 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が大好きでした。それらを組み合わせるのが好きだとは言えません。 cliではなくAPIに焦点を合わせる方が簡単だったようです。
皇帝XLIIによって提案された文字列配列のパラメータはうまく機能します。別の解決策を次の記事に示します。 PowerShellでMSDeployを使用する際の試練と苦難
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 )
}
キースの答え から スペースと引用符を含むパラメーターを使用してPowerShellでexeを実行する方法 リンクした質問を使用して、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>
これは、msdeploy
が見ていたappHostConfig=default
の無効な引数を説明します。
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
誰かに役立つ場合に備えて、別の方法を追加するだけです。
Invoke-Expression "& '[path to msdeploy]\msdeploy.exe' --% -verb:sync -source:contentPath=`'$source`' -dest:contentPath=`'$dest`'"
"-%"はPowerShell 3の新機能です。From here : "コマンドラインの任意の場所に-%シーケンス(2つのダッシュとパーセント記号)を追加するだけで、PowerShellは追加を試みません。その行の残りを解析します。」
実用的な解決策と簡単な修正を見つけました。参照: 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
私たちは同様の問題に直面していました。私たちの修正は以下のようでした、
$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 -エスケープシーケンス/文字です
私は太陽の下ですべてのテクニックを試しましたが、これが私のために働いた唯一のテクニックです(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 )
以下の入力から派生した別のアプローチを次に示します。
$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に対応しています。したがって、エスケープ文字( `)でのラッピング。
上記のすべてが私にとってはうまくいきませんでした、これはうまくいった解決策です:
# 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パスのスペースを取り除くことです。ここには2つのアプローチがあります。 1つは永続的であり、サーバーアクセスが必要です。もう1つは、PowerShellスクリプトのコンテキストで一時的なものです。どちらでも機能しますが、それがあなたの選択肢であるなら、私は最初のものを好みます。
最初のアプローチでは、ジャンクションポイントを作成します。スクリプトの例:
new-item -Path "c:\MS-WebDeploy" -ItemType Junction -Value "c:/Program Files (x86)/iis/Microsoft web deploy v3"
2番目のアプローチでは、PSDriveを作成します(この例ではw)
New-PSDrive -Name "w" -PSProvider FileSystem -Root "C:/Program Files (x86)/iis/Microsoft web deploy v3"
以下の3つのPowerShell変数を使用しています。たとえば、3つすべてにスペースがあると仮定します。
まず、配列を作成し、必要に応じて引数を作成します。
#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
一般に、パス/名前のスペースを取り除くことで、自分自身を大いに助けることができます。時々、それはできません、そして、これはあなたを通り抜けるはずです。
上記の回答からいくつかのアイデアを使用して、次の簡単な関数を考え出しました。
ビルドエージェントで実行している場合、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