2009-11-04 12 views
212

¿Cómo ejecuta el siguiente comando en PowerShell?Cómo ejecutar un archivo EXE en PowerShell con parámetros con espacios y comillas

C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe -verb:sync -source:dbfullsql="Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;" -dest:dbfullsql="Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass"

+0

Véase también http://stackoverflow.com/questions/6224638/powershell-call-msbuild-with-nested-quotation-marks/8468690#8468690 –

+0

Si se refiere a litteraly " en PowerShell "(que interpreto que significa" dentro de un indicador de PowerShell existente), entonces el siguiente ejemplo se puede adaptar fácilmente a sus necesidades. Tenga en cuenta que no hay necesidad de separar el comando de sus parámetros: '# Mostrar cualquier disponible actualizaciones para paquetes npm instalados globalmente utilizando la herramienta npm-check-updates [cadena] $ cmd = 'ncu -g' Write-Verbose -Message $ cmd Invoke-Command -ScriptBlock ([ScriptBlock] :: Create ($ cmd)) ' – user3785010

+0

No tengo idea de cómo usar" mini-markdown "para editar el comentario anterior para hacer que cada línea del código aparecen en una línea separada y el límite de tiempo de 5 minutos para editar el comentario original ha expirado. Si alguien sabe ahora usar "mini-Markdown" para solucionar el problema, volveré a publicar en una forma más legible. La primera línea debe ser la siguiente: herramienta # Mostrar las actualizaciones disponibles de los paquetes de la NGP instalados a nivel mundial utilizando el NPM-Registro de cambios – user3785010

Respuesta

230

Cuando PowerShell ve un comando a partir de una cadena que sólo evalúa la cadena, es decir, que por lo general hace eco a la pantalla, por ejemplo:

PS> "Hello World" 
Hello World 

Si desea PowerShell para interpretar la cadena como un nombre de comando a continuación, utilizar el operador de llamada (&) de esta manera:

PS> & 'C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe' 

Después de que es probable que sólo necesita cotizar pares parámetro/argumento de que conta en espacios y/o caracteres de comillas. Cuando invoca un archivo EXE como este con argumentos complejos de línea de comandos, generalmente es muy útil tener una herramienta que le muestre cómo PowerShell envía los argumentos al archivo EXE. El PowerShell Community Extensions tiene una herramienta de este tipo. Se llama ecoargs. Usted acaba de cambiar el archivo EXE con echoargs - dejando todos los argumentos en su lugar, y le mostrará cómo el archivo EXE recibirá los argumentos, por ejemplo:

PS> echoargs -verb:sync -source:dbfullsql="Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;" -dest:dbfullsql="Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass 

Arg 0 is <-verb:sync> 
Arg 1 is <-source:dbfullsql=Data> 
Arg 2 is <Source=mysource;Integrated> 
Arg 3 is <Security=false;User> 
Arg 4 is <ID=sa;Pwd=sapass!;Database=mydb;> 
Arg 5 is <-dest:dbfullsql=Data> 
Arg 6 is <Source=.\mydestsource;Integrated> 
Arg 7 is <Security=false;User> 
Arg 8 is <ID=sa;Pwd=sapass!;Database=mydb; computername=10.10.10.10 username=administrator password=adminpass> 

Usando echoargs se puede experimentar hasta que salga bien , por ejemplo:

PS> echoargs -verb:sync "-source:dbfullsql=Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;" 
Arg 0 is <-verb:sync> 
Arg 1 is <-source:dbfullsql=Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;> 

Resulta que estaba intentando demasiado antes para mantener las comillas dobles alrededor de la cadena de conexión. Aparentemente eso no es necesario porque incluso cmd.exe los eliminará.

Por cierto, felicitaciones al equipo de PowerShell. Fueron bastante útiles al mostrarme el encantamiento específico de las comillas dobles & para obtener el resultado deseado, si era necesario mantener las comillas dobles internas en su lugar. :-) También se dan cuenta de que esta es un área de dolor, pero se deben a la cantidad de personas afectadas por un problema en particular. Si esto es un área de dolor para usted, vote por favor este PowerShell bug submission.

Para obtener más información sobre cómo analiza PowerShell, echa un vistazo a mi Effective PowerShell blog series - específicamente item 10 - "Understanding PowerShell Parsing Modes"

ACTUALIZACIÓN 4/4/2012: Esta situación se vuelve mucho más fácil de manejar en PowerShell V3. Vea esto blog post for details.

+1

si se utiliza como segundo ejemplo, me sale este error: error: argumento no reconocido '" -source: dbfullsql = "" "Datos". Todos los argumentos deben comenzar con "-". – Vans

+2

Lo siento, no entiendo. Veo que, actualmente, 6 personas han votado por respuesta, así que me falta algo obvio, pero ¿cuál es la respuesta real? ¿Existe alguna regla especial que deba conocer acerca de los parámetros con espacios con PowerShell, o simplemente está sugiriendo llevarlo caso por caso, utilizando EchoArgs para ayudarlo? –

+0

Citar los argumentos suele ser suficiente, pero no siempre. En los casos en que no funciona, el uso de 'echoargs' da una indicación de cómo PowerShell está interpretando los argumentos antes de pasarlos al EXE. –

41

Simplemente agregue el operador & antes del nombre .exe. Aquí es un comando para instalar SQL Server Express en el modo de silencio:

$fileExe = "T:\SQLEXPRADV_x64_ENU.exe" 
$CONFIGURATIONFILE = "T:\ConfSetupSql2008Express.ini" 

& $fileExe /CONFIGURATIONFILE=$CONFIGURATIONFILE 
+16

Esto no responde a la pregunta de cómo usar espacios y comillas en una línea de comandos de powershell. –

8

pude conseguir mi comando similar de trabajo utilizando el siguiente enfoque:

msdeploy.exe -verb=sync "-source=dbFullSql=Server=THESERVER;Database=myDB;UID=sa;Pwd=saPwd" -dest=dbFullSql=c:\temp\test.sql 

Por su comando (no que ayuda tanto ahora), las cosas se verá algo como esto:

msdeploy.exe -verb=sync "-source=dbfullsql=Server=mysource;Trusted_Connection=false;UID=sa;Pwd=sapass!;Database=mydb;" "-dest=dbfullsql=Server=mydestsource;Trusted_Connection=false;UID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass 

Los puntos clave son:

  • Use comillas alrededor del argumento de origen y elimine las comillas insertadas alrededor de la cadena de conexión
  • Utilice los nombres de clave alternativos para crear la cadena de conexión SQL que no tenga espacios. Por ejemplo, use "UID" en lugar de "ID de usuario", "Servidor" en lugar de "Origen de datos", "Conexión de confianza" en lugar de "Seguridad integrada", y así sucesivamente. Solo pude hacer que funcionara una vez que eliminé todos los espacios de la cadena de conexión.

No intenté agregar la parte "nombre del equipo" al final de la línea de comandos, pero espero que esta información ayude a los demás que la lean a obtener el resultado deseado.

+1

Intenté todas las demás respuestas, ¡pero esta fue la única respuesta que funcionó para mí! Gracias por proporcionar esta ruta alternativa. – Sentient

+0

+1 por mencionar los sinónimos de la cadena de conexión – meklarian

4

de escape de cadenas nuevo en PowerShell V3, citado de New V3 Language Features:

Easier Reuse of Command Lines From Cmd.exe

El la web está llena de líneas de comando escritas para Cmd.exe. Estas líneas de comandos funcionan con bastante frecuencia en PowerShell, pero cuando incluyen ciertos caracteres, por ejemplo, un punto y coma (;), un signo de dólar ($) o llaves, debe realizar algunos cambios, probablemente agregando algunas comillas. Esto parecía ser la fuente de muchos dolores de cabeza menores.

Para ayudar a abordar este escenario, agregamos una nueva forma de "escapar" el análisis sintáctico de las líneas de comando. Si usa un parámetro mágico -%, detenemos nuestro análisis normal de su línea de comando y cambiamos a algo mucho más simple. No hacemos coincidir las comillas. No nos detenemos en el punto y coma. No expandimos las variables de PowerShell. Sí expandimos las variables de entorno si usa la sintaxis Cmd.exe (por ejemplo,% TEMP%). Aparte de eso, los argumentos hasta el final de la línea (o tubería, si está tubería) se pasan como están. Aquí está un ejemplo:

PS> echoargs.exe --% %USERNAME%,this=$something{weird} 
Arg 0 is <jason,this=$something{weird}> 
+0

Lo intentaré más tarde. Parece genial. –

9

Esto funcionó para mí:

& 'D:\Server\PSTools\PsExec.exe' @('\\1.1.1.1', '-accepteula', '-d', '-i', $id, '-h', '-u', 'domain\user', '-p', 'password', '-w', 'C:\path\to\the\app', 'java', '-jar', 'app.jar') 

sólo hay que poner caminos o cadenas de conexión en un solo elemento de la matriz y se separaron las otras cosas en un solo elemento de la matriz cada uno.

Hay un montón de otras opciones aquí: https://social.technet.microsoft.com/wiki/contents/articles/7703.powershell-running-executables.aspx

Microsoft debería hacer esta manera más sencilla y compatible con la sintaxis de línea de comandos.

23

que tenían espacios en ambos comandos y parámetros, y esto es lo que funcionó para mí:

$Command = "E:\X64\Xendesktop Setup\XenDesktopServerSetup.exe" 
$Parms = "/COMPONENTS CONTROLLER,DESKTOPSTUDIO,DESKTOPDIRECTOR,LICENSESERVER,STOREFRONT /PASSIVE /NOREBOOT /CONFIGURE_FIREWALL /NOSQL" 

$Prms = $Parms.Split(" ") 
& "$Command" $Prms 

Es básicamente la misma que la respuesta de Akira, pero esto funciona si dinámicamente construir sus parámetros de comando y ponerlos en una variable.

+0

imho este es el mejor! no base64, no strange -% sintaxis que alterna sustitución, reglas normales de sustitución powershell, sin confusión, muy legible. – AnneTheAgile

+0

Esto no funciona. Si su parámetro tiene un nombre de ruta, el nombre de ruta se dividirá en múltiples parámetros. – BrainSlugs83

+0

Buena respuesta. Sin embargo, ¿funcionará con comillas en los parámetros? –

3

Esto funcionó para mí:

PowerShell.exe -Command "& ""C:\Some Script\Path With Spaces.ps1""" 

La clave parece ser que todo el comando se escribe entre comillas exteriores, la "&" signo se utiliza para especificar otro archivo de comandos niño se está ejecutando, y finalmente Frases escapadas (dobles-dobles) en torno a la ruta/nombre del archivo con espacios que desea ejecutar en primer lugar.

Esto también es la finalización de la única solución para el problema de conexión de MS que -El archivo no transfiere códigos de retorno que no sean cero y -El comando es la única alternativa. Pero hasta ahora se pensaba que una limitación de -Command era que no admitía espacios. También actualicé ese comentario.

http://connect.microsoft.com/PowerShell/feedback/details/750653/powershell-exe-doesn-t-return-correct-exit-codes-when-using-the-file-option

+0

Esto no está relacionado con la pregunta de operaciones, específicamente preguntó cómo ejecutar el comando largo en su publicación en PowerShell. No se cómo ejecutar un script powershell con espacios en la ruta del archivo. – leinad13

+0

Lea el título de la pregunta, los espacios son el problema, no la longitud. Esta es una respuesta válida a tales problemas, por lo que vale la pena compartir. ¿Tuviste el mismo problema y realmente lo intentas? Si quiere mejorar, envíe una edición que incluya el comando real en la pregunta y la aceptaré. –

3

una respuesta alternativa es usar un interruptor Base64 comando codificado:

powershell -EncodedCommand "QwA6AFwAUAByAG8AZwByAGEAbQAgAEYAaQBsAGUAcwBcAEkASQBTAFwATQBpAGMAcgBvAHMAbwBmAHQAIABXAGUAYgAgAEQAZQBwAGwAbwB5AFwAbQBzAGQAZQBwAGwAbwB5AC4AZQB4AGUAIAAtAHYAZQByAGIAOgBzAHkAbgBjACAALQBzAG8AdQByAGMAZQA6AGQAYgBmAHUAbABsAHMAcQBsAD0AIgBEAGEAdABhACAAUwBvAHUAcgBjAGUAPQBtAHkAcwBvAHUAcgBjAGUAOwBJAG4AdABlAGcAcgBhAHQAZQBkACAAUwBlAGMAdQByAGkAdAB5AD0AZgBhAGwAcwBlADsAVQBzAGUAcgAgAEkARAA9AHMAYQA7AFAAdwBkAD0AcwBhAHAAYQBzAHMAIQA7AEQAYQB0AGEAYgBhAHMAZQA9AG0AeQBkAGIAOwAiACAALQBkAGUAcwB0ADoAZABiAGYAdQBsAGwAcwBxAGwAPQAiAEQAYQB0AGEAIABTAG8AdQByAGMAZQA9AC4AXABtAHkAZABlAHMAdABzAG8AdQByAGMAZQA7AEkAbgB0AGUAZwByAGEAdABlAGQAIABTAGUAYwB1AHIAaQB0AHkAPQBmAGEAbABzAGUAOwBVAHMAZQByACAASQBEAD0AcwBhADsAUAB3AGQAPQBzAGEAcABhAHMAcwAhADsARABhAHQAYQBiAGEAcwBlAD0AbQB5AGQAYgA7ACIALABjAG8AbQBwAHUAdABlAHIAbgBhAG0AZQA9ADEAMAAuADEAMAAuADEAMAAuADEAMAAsAHUAcwBlAHIAbgBhAG0AZQA9AGEAZABtAGkAbgBpAHMAdAByAGEAdABvAHIALABwAGEAcwBzAHcAbwByAGQAPQBhAGQAbQBpAG4AcABhAHMAcwAiAA==" 

Cuando decodificado, verá que es fragmento original de la OP con todos los argumentos y comillas dobles conservados.

powershell.exe -EncodedCommand 

Accepts a base-64-encoded string version of a command. Use this parameter 
to submit commands to Windows PowerShell that require complex quotation 
marks or curly braces. 

El mandamiento original:

C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe -verb:sync -source:dbfullsql="Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;" -dest:dbfullsql="Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass" 

Se convierte en esto cuando codificado como base 64:

QwA6AFwAUAByAG8AZwByAGEAbQAgAEYAaQBsAGUAcwBcAEkASQBTAFwATQBpAGMAcgBvAHMAbwBmAHQAIABXAGUAYgAgAEQAZQBwAGwAbwB5AFwAbQBzAGQAZQBwAGwAbwB5AC4AZQB4AGUAIAAtAHYAZQByAGIAOgBzAHkAbgBjACAALQBzAG8AdQByAGMAZQA6AGQAYgBmAHUAbABsAHMAcQBsAD0AIgBEAGEAdABhACAAUwBvAHUAcgBjAGUAPQBtAHkAcwBvAHUAcgBjAGUAOwBJAG4AdABlAGcAcgBhAHQAZQBkACAAUwBlAGMAdQByAGkAdAB5AD0AZgBhAGwAcwBlADsAVQBzAGUAcgAgAEkARAA9AHMAYQA7AFAAdwBkAD0AcwBhAHAAYQBzAHMAIQA7AEQAYQB0AGEAYgBhAHMAZQA9AG0AeQBkAGIAOwAiACAALQBkAGUAcwB0ADoAZABiAGYAdQBsAGwAcwBxAGwAPQAiAEQAYQB0AGEAIABTAG8AdQByAGMAZQA9AC4AXABtAHkAZABlAHMAdABzAG8AdQByAGMAZQA7AEkAbgB0AGUAZwByAGEAdABlAGQAIABTAGUAYwB1AHIAaQB0AHkAPQBmAGEAbABzAGUAOwBVAHMAZQByACAASQBEAD0AcwBhADsAUAB3AGQAPQBzAGEAcABhAHMAcwAhADsARABhAHQAYQBiAGEAcwBlAD0AbQB5AGQAYgA7ACIALABjAG8AbQBwAHUAdABlAHIAbgBhAG0AZQA9ADEAMAAuADEAMAAuADEAMAAuADEAMAAsAHUAcwBlAHIAbgBhAG0AZQA9AGEAZABtAGkAbgBpAHMAdAByAGEAdABvAHIALABwAGEAcwBzAHcAbwByAGQAPQBhAGQAbQBpAG4AcABhAHMAcwAiAA== 

y aquí es cómo replicar en casa:

$command = 'C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe -verb:sync -source:dbfullsql="Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;" -dest:dbfullsql="Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass"' 
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command) 
$encodedCommand = [Convert]::ToBase64String($bytes) 
$encodedCommand 

# The clip below copies the base64 string to your clipboard for right click and paste. 
$encodedCommand | Clip 
3

Probé todas las sugerencias, pero fue sti No se puede ejecutar msiexec.exe con parámetros que contengan espacios. Así que mi solución terminó usando System.Diagnostics.ProcessStartInfo:

# can have spaces here, no problems 
$settings = @{ 
    CONNECTION_STRING = "... ..." 
    ENTITY_CONTEXT = "... ..." 
    URL = "..." 
} 

$settingsJoined = ($settings.Keys | % { "$_=""$($settings[$_])""" }) -join " " 
$pinfo = New-Object System.Diagnostics.ProcessStartInfo 
$pinfo.WorkingDirectory = $ScriptDirectory 
$pinfo.FileName = "msiexec.exe" 
$pinfo.RedirectStandardError = $true 
$pinfo.RedirectStandardOutput = $true 
$pinfo.UseShellExecute = $false 
$pinfo.Arguments = "/l* install.log /i installer.msi $settingsJoined" 
$p = New-Object System.Diagnostics.Process 
$p.StartInfo = $pinfo 
$p.Start() | Out-Null 
$p.WaitForExit() 
$stdout = $p.StandardOutput.ReadToEnd() 
0

Por lo tanto, me encontré con un problema similar y eligió para resolverlo la manera siguiente:

  1. escapar de tu comillas (") caracteres con un acento grave (`)
  2. rodean su nueva expresión con comillas (")
  3. Usando el operador de llamada (&), ejecute el comando invoke-expression en la nueva cadena

solución Ejemplo:

& { invoke-expression "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe -verb:sync -source:dbfullsql=`"Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`" -dest:dbfullsql=`"Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`",computername=10.10.10.10,username=administrator,password=adminpass`"" }

0

En caso de que alguien se pregunta cómo basta con ejecutar un archivo ejecutable:

.....> \ archivo..exe

o

......> completa \ ruta \ a \ file.exe

0

Hay algunos métodos bastante que puede utilizar para hacerlo.

There are other methods like using the Call Operator (&), Invoke-Expression cmdlet etc. But they are considered unsafe. Microsoft recommends using Start-Process.

Método 1

Un ejemplo sencillo

Start-Process -NoNewWindow -FilePath "C:\wamp64\bin\mysql\mysql5.7.19\bin\mysql" -ArgumentList "-u root","-proot","-h localhost" 

En su caso

Start-Process -NoNewWindow -FilePath "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" -ArgumentList "-verb:sync","-source:dbfullsql=`"Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`"","-dest:dbfullsql=`"Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`"","computername=10.10.10.10","username=administrator","password=adminpass" 

En este método se separa cada parámetro en el ArgumentList el uso de comas.

Método 2

simple Ejemplo

Start-Process -NoNewWindow -FilePath "C:\wamp64\bin\mysql\mysql5.7.19\bin\mysql" -ArgumentList "-u root -proot -h localhost" 

En su caso

Start-Process -NoNewWindow -FilePath "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" -ArgumentList "-verb:sync -source:dbfullsql=`"Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`" -dest:dbfullsql=`"Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`",computername=10.10.10.10,username=administrator,password=adminpass" 

Este método es más fácil ya que permite escribir sus parámetros de una sola vez.

Note that in powershell to represent the quotation mark (") in a string you should insert the grave accent (`) (This is the key above the Tab key in the US keyboard).

-NoNewWindow parameter is used to display the new process in the current console window. By default Windows PowerShell opens a new window.

Referencias: Powershell/Scripting/Start-Process

Cuestiones relacionadas