2010-10-08 10 views
12

Obviamente no sé lo que estoy haciendo.¿Qué pasa con esta línea de comando de PowerShell que cotiza/escapa?

Finalmente he conseguido que este comando de PowerShell funcione. Pero no puedo entender por qué funciona.

Mi preocupación es el final "" caracteres:

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

¿Por qué necesito dobles comillas dobles?

Mi IDE (PowerGUI) dice que la línea no finalizó correctamente, pero es la única forma en que puedo ejecutar el comando como lo desee.

¿Qué es lo que yo, y el IDE, no sé sobre el qouting en PowerShell?


Una pequeña salida de echoargs:

Si me quedo:

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

me sale:

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

Si me quedo sin las dobles comillas dobles, Obtengo:

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> 

Otra cosa que hay que notar es que el comando anterior solo funciona si usa = en lugar de: en el último argumento.

Esto no funcionará:

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

EDITAR

Ahora he intentado la solución matriz de esta manera:

$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 

sigo teniendo el mismo error:

Error: argumento no reconocido '"-postSyncOnSucces s: runCommand = powershell -Command c: \ temp \ kslog \ remotetasks.ps1 Implementar "'. Todos los argumentos deben comenzar con "-".

¿Estoy haciendo algo nuevo mal aquí?

Respuesta

11

Esto es un problema notorio. El ticket "Ejecutar comandos que requieren presupuestos y variables es prácticamente imposible" es el error más votado: https://connect.microsoft.com/PowerShell/Feedback

También puede encontrar algunas soluciones. Pero le recomendaría que compusiera todos los parámetros como una matriz y use el operador & para invocar un comando nativo con esta matriz. Ver las respuestas y ejemplos: Running an EXE file using PowerShell from a directory with spaces in it y Executing a Command stored in a Variable from Powershell

yo no trabajo con msdeploy.exe y no puede proporcionar un cierto código de demostración para su caso. Pero apliqué este enfoque a muchos otros comandos nativos difíciles bastante bien. Por favor, pruébalo y cuéntanos los resultados.

P.S. Técnicamente, esta no es exactamente una respuesta a sus preguntas, pero supongo que todavía está buscando una forma práctica de hacerlo, por lo que podría ser útil.

+0

¡Gracias por la respuesta! Estoy lejos del código este fin de semana, pero probaré tus sugerencias cuando regrese el lunes. Tienes razón, que técnicamente esto no es una respuesta a por qué funciona el doble double-qoutes ... pero si es un error, y no por diseño, entonces no valdría la pena obtener una comprensión más profunda de todos modos. Regresaré en breve. – asgerhallas

+0

So. He intentado todo tipo de combinaciones de usar una matriz para los parámetros. Nada parece funcionar. ¿Tienes una idea de por qué? – asgerhallas

+0

He editado la pregunta con mi nuevo intento ... – asgerhallas

1

Una de las áreas en falla aquí es la incapacidad de PowerShell para hacer frente a la traducción de los espacios en blanco entre "Archivos de programa" expresados ​​en cmd-based msdeploy.

Esta es una solución extremadamente base, y aprovecha anticuados limitaciones de DOS, pero las siguientes referencias no está en blanco se puede utilizar en su lugar:

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

Es cojo, pero funciona.

También puede crear una función que llame a cmd y ejecute su comando. Este ejemplo también asume que lo que está intentando llamar (msdeploy, etc.) está en la ruta.

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

Finalmente descubrí cómo hacer esto. Aquí hay una secuencia de comandos de muestra:

$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

Esto funcionó para mí, finalmente. ¡Gracias! – ydd1987

Cuestiones relacionadas