2010-10-08 7 views
12

Ovviamente non so cosa sto facendo.Cosa succede con questa riga di comando di PowerShell che cita/fugge?

Ho finalmente ottenuto il comando di PowerShell per funzionare. Ma non riesco a capire perché funzioni.

La mia preoccupazione è la finale "" caratteri:

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

Perché ho bisogno di doppie virgolette?

Il mio IDE (PowerGUI) dice che la linea non è terminata correttamente, ma è l'unico modo in cui posso far funzionare il comando come desiderato.

Che cos'è, che io e l'IDE non sappiamo su qouting in PowerShell?


Un po 'di uscita dal echoargs:

Se corro:

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

ottengo:

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

Se corro senza le doppie virgolette, Ottengo:

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> 

Un'altra cosa da notare è che il comando precedente funziona solo se utilizza = anziché: nell'ultimo argomento.

Questo non funziona:

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

EDIT

Ora ho provato la soluzione di matrice in questo modo:

$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 

ancora ottengo lo stesso errore:

Errore: argomento "" -postSyncOnSucces non riconosciuto s: runCommand = powershell -Command c: \ temp \ kslog \ remotetasks.ps1 Distribuisci "'. Tutti gli argomenti devono iniziare con "-".

Sto facendo qualcosa di nuovo sbagliato qui?

risposta

11

Questo è un problema noto. Il ticket "Eseguire comandi che richiedono virgolette e variabili è praticamente impossibile" è il bug più votato: https://connect.microsoft.com/PowerShell/Feedback

È possibile trovare anche alcune soluzioni alternative. Ma ti consiglio di comporre tutti i parametri come array e utilizzare l'operatore & per richiamare un comando nativo con questo array. Vedi le risposte e gli esempi: Running an EXE file using PowerShell from a directory with spaces in it e Executing a Command stored in a Variable from Powershell

non ho lavorato con msdeploy.exe e non in grado di fornire qualche codice demo per il vostro caso. Ma ho applicato questo approccio a molti altri comandi nativi difficili abbastanza bene. Per favore, provalo e facci sapere i risultati.

P.S. Tecnicamente questa non è esattamente una risposta alle tue domande, ma presumo che tu stia ancora cercando un modo pratico per farlo, quindi potrebbe comunque essere utile.

+0

Grazie per la risposta! Sono lontano dal codice questo fine settimana, ma proverò i tuoi suggerimenti quando tornerò lunedì. Hai ragione, non è tecnicamente una risposta al perché il doppio doppio qoutes funzioni ... ma se si tratta di un bug, e non di una progettazione, potrebbe non valere la pena approfondire comunque la comprensione. Tornerò tra poco. – asgerhallas

+0

così. Ho provato tutti i tipi di combinazioni di utilizzare un array per i parametri. Niente sembra funzionare. Hai un'idea del perché? – asgerhallas

+0

Ho modificato la domanda con il mio nuovo tentativo ... – asgerhallas

1

Una delle aree in difetto qui è l'impossibilità di PowerShell di far fronte alla traduzione degli spazi bianchi tra "Programmi" espressi nel cmdeploy basato su cmd.

Si tratta di una soluzione estremamente di base, e sfrutta le limitazioni antiquati DOS, ma i seguenti riferimenti che non sono spazi possono essere utilizzati al loro posto:

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

E 'zoppo, ma funziona.

È inoltre possibile creare una funzione che chiama cmd ed esegue il comando. Questo esempio presuppone anche che ciò che stai cercando di chiamare (msdeploy, ecc.) Sia nel percorso.

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

Ho finalmente scoperto come farlo. Ecco uno script di esempio:

$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

Questo ha funzionato per me, finalmente. Grazie! – ydd1987