Как вы вызываете msdeploy из powershell, когда параметры имеют пробелы?
У меня проблема с пробелами в моих параметрах, которые я пытаюсь отправить в msdeploy из скрипта powershell.
Есть ряд других связанных статей, но ни одна из них не решает проблему.
Проблемы с использованием Power Shell и MSDeploy.
Подобная проблема SO, которая не работает: Как запустить exe в powershell с параметрами с пробелами и кавычками
Ошибка PowerShell: Выполнение команд, требующих кавычек и переменных, практически невозможно
Еще одна проблема SO, которая не работает: передача параметров в PowerShell 2.0
Простейший пример, который успешно, а затем терпит неудачу, когда я делаю его более сложным, - это просто дамп веб-сайта по умолчанию.
$ msdeploy = "C: \ Program Files \ IIS \ Microsoft Web Deploy \ msdeploy.exe"
& $ msdeploy -verb: dump -source: appHostConfig = `'веб-сайт по умолчанию`' -verbose
== УСПЕХ
Вот этот?
$ sitename = "веб-сайт по умолчанию"
& $ msdeploy -verb: dump -source: appHostConfig = $ sitename -verbose
== FAIL со следующей ошибкой
msdeploy.exe: Ошибка: нераспознанный аргумент "-source:"appHostConfig=default ". Все аргументы должны начинаться с "-".
На C: \ xxx \ test.ps1: 122 char: 6
+ &
+ CategoryInfo: NotSpecified: (Ошибка: Unrecogn... начинается с "-".: String) [], RemoteException
+ FullyQualifiedErrorId: NativeCommandError
Количество ошибок: 1.
Следующие варианты также не удалось
#ПОТЕРПЕТЬ ПОРАЖЕНИЕ
$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, а не на клиенте.
РЕДАКТИРОВАТЬ:
Параметры в массиве строк, предложенные Emperor XLII, работают хорошо. Альтернативное решение представлено в следующей статье: Испытания и трудности использования MSDeploy с 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 )
}
8 ответов
Используя технику из ответа Кейта на Как запустить exe в powershell с параметрами с пробелами и кавычками, с которыми вы связаны, выполняя 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
Просто добавьте другой способ, если он кому-нибудь пригодится:
Invoke-Expression "& '[path to msdeploy]\msdeploy.exe' --% -verb:sync -source:contentPath=`'$source`' -dest:contentPath=`'$dest`'"
"-%" является новым для powershell 3. Отсюда: "Вы просто добавляете последовательность -% (две черты и знак процента) в любом месте командной строки, и 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 - escape-последовательность / символ
Я испробовал каждую технику под солнцем, и это единственное, что сработало для меня (используя 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 в его папке установки по умолчанию, которая содержит пробелы. Отсюда перенос с escape-символом (`).
Все вышеперечисленное не работает для меня, это решение, которое работало:
# 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, так как при работе под агентом сборки он иногда не распознает PATH для 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
Эта проблема, безусловно, существует уже давно, и недавно я потратил некоторое время на ее решение. Результат оказался для меня успешным, поэтому я опубликую его здесь в надежде, что он поможет другим, кто найдет этот вопрос в будущем.
Первая проблема, которую необходимо решить, - это избавиться от пробелов в пути 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:\ файлы развертывания \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 и установите escape-последовательность 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
В общем, вы можете сильно помочь себе, избавившись от пробелов в ваших путях / именах. Иногда это невозможно сделать, и это должно помочь вам.