2010-10-08 2 views
12

Я, очевидно, не знаю, что делаю.Что происходит с этой командной строкой 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:

Если я бегу:

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"" 

EDIT

Теперь я попробовал решение массива, как это:

$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 

Я все еще получаю ту же ошибку:

Ошибка: непризнанный аргумент '"-postSyncOnSucces s: runCommand = powershell -Command c: \ temp \ kslog \ remotetasks.ps1 Развернуть «'. Все аргументы должны начинаться с «-».

Я делаю что-то новое здесь неправильно?

ответ

11

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

Вы также можете найти несколько обходных решений. Но я бы рекомендовал вам составить все параметры в виде массива и использовать оператор & для вызова собственной команды с этим массивом. Смотрите ответы и примеры: Running an EXE file using PowerShell from a directory with spaces in it и Executing a Command stored in a Variable from Powershell

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

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

+0

Благодарим за ответ! В этот уик-энд я прочь от кода, но я попробую ваши предложения, когда вернусь в понедельник. Вы правы, что это технически не является ответом на то, почему работают двойные двойные qoutes ... но если это ошибка, а не по дизайну, то, возможно, не стоит больше углубляться в понимание. Я скоро вернусь. – asgerhallas

+0

So. Я пробовал всевозможные комбинации использования массива для параметров. Ничто не работает. У вас есть идея, почему? – asgerhallas

+0

Я отредактировал вопрос с моей новой попыткой ... – asgerhallas

1

Одна из проблемных областей заключается в неспособности PowerShell справиться с переводом пробелов между «Программными файлами», выраженными в msdploy.

Это чрезвычайно щелочной раствор, и использует устаревшие ограничения 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") 
} 
3

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

$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 
+0

Это сработало для меня, наконец. Спасибо! – ydd1987

Смежные вопросы