Что случилось с этим цитированием / экранированием командной строки PowerShell?
Я, очевидно, не знаю, что я делаю.
Я наконец получил эту команду 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 - не знаю насчет qouting в PowerShell?
Небольшой вывод от эхо-сигналов:
Если я бегу:
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>
Если я запускаю без двойных двойных кавычек, я получаю:
Arg 0 is <-postSync=runCommand=powershell>
Arg 1 is <-NoLogo>
Arg 2 is <-NoProfile>
Arg 3 is <-Command>
Arg 4 is <\remotetasks.ps1>
Arg 5 is <Deploy>
Следует также отметить, что приведенная выше команда работает, только если она использует = вместо: в последнем аргументе.
Это не сработает:
-postSync:runCommand="powershell -NoLogo -NoProfile -Command $server_temp_directory\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" ". Все аргументы должны начинаться с "-".
Я что-то здесь не так делаю?
3 ответа
Это пресловутая проблема. Билет "Выполнение команд, требующих кавычек и переменных практически невозможно" - это самая популярная ошибка: https://connect.microsoft.com/PowerShell/Feedback
Вы также можете найти там несколько обходных путей. Но я бы порекомендовал вам составить все параметры в виде массива и использовать &
оператор для вызова собственной команды с этим массивом. См. Ответы и примеры: Запуск EXE-файла с помощью PowerShell из каталога с пробелами в нем и Выполнение команды, хранящейся в переменной из Powershell.
Я не работал с msdeploy.exe
и не может предоставить какой-либо демонстрационный код для вашего случая. Но я применил этот подход ко многим другим хитрым нативным командам достаточно хорошо. Пожалуйста, попробуйте и дайте нам знать результаты.
PS Технически это не совсем ответ на ваши вопросы, но я предполагаю, что вы все еще ищете практический способ сделать это, так что он все еще может быть полезным.
Я наконец узнал, как это сделать. Вот пример сценария:
$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
Одна из проблемных областей - это неспособность PowerShell справиться с переводом пробела между "Программными файлами", выраженного в msdeploy на основе cmd.
Это чрезвычайно базовое решение, в котором используются устаревшие ограничения 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")
}