2010-10-08 18 views
12

Oczywiście nie wiem, co robię.Co się dzieje z tym wierszem poleceń programu PowerShell, cytując/ukrywając?

W końcu mam to polecenie PowerShell do pracy. Ale nie mogę zrozumieć, dlaczego to działa.

Moim problemem jest ostateczna „” znaków:

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

Dlaczego muszę podwójne podwójne cytaty?

Mój IDE (PowerGUI) mówi, że linia nie jest poprawnie zakończona, ale jest to jedyny sposób, w jaki mogę uruchomić komendę zgodnie z oczekiwaniami.

Co to jest, że ja - i IDE - nie wiem o tematach w PowerShell?


Trochę wyjście z echoargs:

Jeśli biegnę:

echoargs -postSync=runCommand="powershell -NoLogo -NoProfile -Command $server_temp_directory\remotetasks.ps1 Deploy"" 

uzyskać:

Arg 0 is <-postSync=runCommand=powershell -NoLogo -NoProfile -Command \remotetasks.ps1 Deploy> 

Jeśli uruchomić bez podwójnymi cudzysłowami, Otrzymuję:

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> 

Inną rzeczą, którą należy zauważyć, jest to, że powyższe polecenie działa tylko wtedy, gdy używa = zamiast: w ostatnim argumencie.

To nie zadziała:

-postSync:runCommand="powershell -NoLogo -NoProfile -Command $server_temp_directory\remotetasks.ps1 Deploy"" 

EDIT

Teraz Próbowałem rozwiązanie tablicy tak:

$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 

wciąż otrzymuję ten sam błąd:

Błąd: nierozpoznany argument "" -postSyncOnSucces s: runCommand = powershell - Polecenie c: \ temp \ kslog \ remotetasks.ps1 Rozmieść "". Wszystkie argumenty muszą zaczynać się od "-".

Czy robię coś niedobrego tutaj?

Odpowiedz

11

To jest głośny problem. Bilet "Wykonanie poleceń wymagających wycen i zmiennych jest praktycznie niemożliwy" jest najczęściej wybieranym błędem: https://connect.microsoft.com/PowerShell/Feedback

Można tam również znaleźć kilka obejść. Ale polecam Ci skomponowanie wszystkich parametrów jako array i użycie operatora & do wywołania natywnego polecenia z tą tablicą. Zobacz odpowiedzi i przykłady: Running an EXE file using PowerShell from a directory with spaces in it i Executing a Command stored in a Variable from Powershell

nie pracowałem z msdeploy.exe i nie może zapewnić pewne kod demo dla swojej sprawy. Ale zastosowałem to podejście do wielu innych trudnych natywnych poleceń wystarczająco dobrze. Proszę, spróbuj i daj znać wyniki.

P.S. Z technicznego punktu widzenia nie jest to dokładnie odpowiedź na twoje pytania, ale zakładam, że wciąż poszukujesz praktycznego sposobu na zrobienie tego, więc nadal może być pomocne.

+0

Dziękuję za odpowiedź! W ten weekend jestem z dala od kodu, ale wypróbuję twoje sugestie, kiedy wrócę w poniedziałek. Masz rację, że to nie jest technicznie odpowiedź na pytanie, dlaczego działa podwójna podwójna kolejka ... ale jeśli jest to błąd, a nie projekt, to i tak może nie być warta głębszego zrozumienia. Wrócę wkrótce. – asgerhallas

+0

So. Próbowałem wszystkich rodzajów kombinacji użycia tablicy dla parametrów. Nic nie działa. Czy masz pomysł, dlaczego? – asgerhallas

+0

Edytowałem pytanie z moją nową próbą ... – asgerhallas

1

Jednym z obszarów, w którym leży błąd, jest niezdolność PowerShell do radzenia sobie z tłumaczeniem białych znaków pomiędzy "plikami programów" wyrażonymi w msdeploy opartym na cmd.

Jest to niezwykle baza rozwiązanie, i wykorzystuje przestarzałe ograniczenia DOS, ale poniższe informacje non-białe znaki mogą być stosowane w ich miejsce:

\Program Files\ ... \Progra~1\ 
\Program Files (x86)\ ... \Progra~2\ 

To lame, ale to działa.

Można również utworzyć funkcję, która wywołuje cmd i wykonuje polecenie. W tym przykładzie zakłada się również, że to, co próbujesz wywołać (msdeploy, itp.) Znajduje się w ścieżce.

function PushToTarget() { 
    cmd.exe /C $("msdeploy.exe -verb:sync -source:apphostconfig=yourwebapp-dev -dest:archivedir=d:\backup") 
} 
3

W końcu dowiedziałem się, jak to zrobić. Oto przykładowy skrypt:

$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

W końcu to dla mnie zadziałało. Dziękuję Ci! – ydd1987