Что случилось с этим цитированием / экранированием командной строки PowerShell? - PullRequest
12 голосов
/ 08 октября 2010

Я явно не знаю, что делаю.

Я наконец получил команду 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, не знаем о цитировании в 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 ]

11 голосов
/ 08 октября 2010

Это печально известная проблема.Тикет «Выполнение команд, требующих кавычек и переменных практически невозможно» - это наиболее проголосовавшая ошибка: https://connect.microsoft.com/PowerShell/Feedback

Здесь вы также можете найти несколько обходных путей.Но я бы порекомендовал вам составить все параметры как массив и использовать оператор & для вызова собственной команды с этим массивом.См. Ответы и примеры: Запуск EXE-файла с помощью PowerShell из каталога с пробелами в нем и Выполнение команды, хранящейся в переменной из Powershell

Я не сделалработать с msdeploy.exe и не может предоставить демо-код для вашего случая.Но я применил этот подход ко многим другим хитрым нативным командам достаточно хорошо.Пожалуйста, попробуйте и дайте нам знать результаты.

PS Технически это не совсем ответ на ваши вопросы, но я предполагаю, что вы все еще ищете практический способ сделать это, так что он все еще может быть полезным.

3 голосов
/ 08 августа 2013

Я наконец-то узнал, как это сделать. Вот пример сценария:

$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
1 голос
/ 14 февраля 2013

Одна из проблемных областей - неспособность 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")
}
...