2010-01-11 12 views
31

Tengo un script de PowerShell que se conecta a un sitio web y analiza sus datos devueltos (Se trata de importar un archivo SQL previamente cargado en la base de datos del sitio web) . La secuencia de comandos de PowerShell usa wget, algo que luego puedo reemplazar por una función nativa.El script de Powershell se atasca, no sale cuando se lo llama desde el archivo por lotes

El proceso de importación está incrustado en un script que se ejecuta mediante un programa de terceros llamado scriptFTP.

La escritura funciona bien cuando lo llamo desde un único archivo .bat, así:

powershell "& "C:\data\etc\run_import_script.ps1" 
exit %ERRORLEVEL% 

Sin embargo, cuando llamo a este archivo .bat desde dentro del contexto más amplio ScriptFTP, ocurre lo siguiente:

  • El script de PowerShell se ejecuta. Confirmé esto enviándome un correo electrónico cada vez que se llamaba el script de importación remota.
  • Parece que PowerShell no sale y la ejecución de scripts se bloquea. Todavía puedo cancelar todo usando Ctrl + C, pero los siguientes comandos nunca se ejecutan.

Cuando cambio el archivo por lotes a lo siguiente:

start powershell "& "C:\data\etc\run_import_script.ps1" 
exit %ERRORLEVEL% 

que trabaja , que ejecuta el script de PowerShell en una nueva consola, pero no puedo agarrar el nivel de error que devuelve PowerShell.

He intentado llamar directamente a PowerShell desde ScriptFTP, omitiendo el archivo por lotes, pero con el mismo resultado: simplemente se atasca.

No se muestra ninguna salida que tenga la secuencia de comandos de PowerShell usando Write-Output o Write-Host.

Todos los programas se ejecutan bajo el mismo usuario, yo.

¿Alguien tiene alguna idea de qué hacer?

+0

Las comillas dobles no coinciden, quizás sea un problema de formato de SO. Por cierto, si usa PowerShell 2.0, debe usar un archivo, por ejemplo, powershell -file c: \ data \ etc \ run_import_script.ps1 –

+0

@Keith, las tres citas son intencionales, consulte aquí: http://stackoverflow.com/questions/2035193/how-to-run-a-powershell-script I Estoy en 1.0 pero considerando cambiarme. Aclamaciones. –

+0

cualquier solución final con el código fuente completo al respecto? – Kiquenet

Respuesta

16

Intenta agregar el parámetro/WAIT. Mantendrá .bat esperando hasta que se complete el script de PowerShell.

START /WAIT powershell "& "C:\data\etc\run_import_script.ps1" 
+2

Saludos, esto funciona muy bien, pero no puedo capturar la salida de Powershell de esa manera, que necesito incluir en la salida de la consola en caso de que haya un error. –

+0

No estoy seguro sobre la parte donde parece colgarse la PS. ¿Qué está sucediendo dentro del script de PS? Quizás es algo sutil que solo aparece cuando se lo llama desde un script. Es extraño, lo sé, pero lo he visto antes. Además, creo que% ERRORLEVEL% va a tener los resultados para PowerShell.exe, pero los resultados de la secuencia de comandos. Por lo tanto, siempre que PowerShell.exe se ejecute hasta su finalización, devolverá 0, independientemente de lo que sucedió dentro del script .ps1. – aphoria

+0

También puede agregar/MIN parámetro para minimizar la ventana de powershell durante la ejecución. – Monsignor

0

PowerShell tiene, al menos lo que yo considero, un comportamiento extraño al ser invocado de esta manera. En resumen, no trata los argumentos de la línea de comandos que se pasan a powershell.exe como scripts para ejecutar. En cambio, los trata como un comando para ejecutar. Esto se debe a que el valor predeterminado para powershell.exe es -command - ver powershell.exe /? para obtener información adicional.

C:\>powershell "'Hello'" 
Hello 

Lo que tendrá que hacer, es crear una cadena inteligente de entrada a "fuente" la secuencia de comandos que desea ejecutar:

C:\>powershell ". .\test.ps1" 
Hello, World! 

En cuanto a la salida, una vez que la secuencia de comandos se ejecuta correctamente , solo debería ser una cuestión de capturar STDOUT o lo que sea que termine encajando con su script.

Ejemplo completo

test.bat

@echo off 
powershell.exe ". .\test.ps1" 

test.ps1

"Hello, World!" 

invocar el comando:

test.bat > test.txt 

Un d verifique que la salida fue capturada:

C:\>type test.txt 
Hello, World! 
+1

Saludos Goyuix, esto es muy bueno saber. Tristemente, incluso así el comportamiento es el mismo: la ejecución simplemente se congela. No obtengo salida alguna. Puedo Ctrl + C todo en cualquier momento, pero no pasará nada. Si utilizo 'START/WAIT powershell.exe' como se sugiere en la otra respuesta, se ejecuta, pero no puedo ver el resultado. Muy extraño ... –

1

si eso es exactamente lo que está en su archivo es porque usted tiene comillas no coincidentes. Powershell está esperando la última cita.

2

Si desea capturar el resultado de los comandos powershell.exe, también puede usar el parámetro/B para forzar el proceso para que se ejecute en el mismo shell de comandos .

Acabamos de ver una instancia muy extraña de este problema. Un archivo por lotes que contiene la llamada powershell.exe -command ... funcionó bien localmente pero se detuvo como se describió anteriormente cuando el archivo por lotes se ejecutó en el contexto de un comando msdeploy -postSync. Después de experimentar con process.Kill() para forzar PowerShell para dejar de fumar, que encendió en el uso de START /WAIT /B PowerShell.exe ..

Ni idea de por qué esto debería funcionar, pero lo hace ...

16

Desde mi experiencia, PowerShell.exe puede ejecutar fácilmente scripts desde dentro de un archivo por lotes o script de shell de una manera predecible usando el modificador de archivo. No es necesario usar el comando de Inicio.

La cosa importante que hacer es añadir

< nul 

a la línea de comandos desde un archivo por lotes. Mi investigación ha demostrado que PowerShell ejecuta los comandos en el script indicado a través del modificador -File y luego espera comandos adicionales de PowerShell desde la entrada estándar (mi breve experimentación con el conmutador -Command demostró un comportamiento similar). Al redirigir la entrada estándar a nul, una vez que PowerShell termina de ejecutar el script y "lee el final del archivo" desde la entrada estándar, PowerShell finaliza.

Cuando se invoca PowerShell desde Cygwin, utilice

< /dev/null 

Por ejemplo, me he encontrado scripts de PowerShell de Cygwin utilizando variables de shell, así:

PowerShell.exe -ExecutionPolicy RemoteSigned -File $_powershellscriptpath $_firstscriptparameter < /dev/null 

favor escribir un comentario si tu experiencia variaba de la mía - Gordon

+5

Gracias por esto, muy útil. Encontré una alternativa que funciona cuando no se inicia desde un shell (y no controla las secuencias) es utilizar el argumento "-InputFormat None" para powershell.exe para desactivar la secuencia de entrada. – chillitom

0

El problema es que el proceso de Powershell continúa para ejecutarse después de ejecutar el script. Esto significa que no ha salido y, por lo tanto, no hay un código de salida. Tengo un problema similar cuando intento ejecutar un script de Powershell desde C# que hace cosas cuando termina, excepto que nunca termina ...

Hacky, pero la única solución que he encontrado es poner Stop-Process -processname powershell al final de la secuencia de comandos .ps1. Esto elimina el proceso de PowerShell (y todas las ventanas de PowerShell que ha abierto desafortunadamente) pero parece funcionar. Podría funcionar también para tu script.

0

Tuve el problema exacto, intentábamos integrar los scripts power shell en otro sistema y seguía generando un error de tiempo de espera. Probablemente debido al problema mencionado por Gordon Smith, su solución podría funcionar. Pero para mí, prefiero tener el control completo de mi script desde dentro del script y no depender de la manera en que se lo llama.

$ pid está construido en variable con el PID. Lo siguiente terminará el proceso actual de PowerShell y dejará intactos los otros. De esta forma, cualquiera puede llamar a su script como normal y funcionará como se espera.

Stop-Process $pid 
0

simplemente puede añadir un comando de 'salida' al final de la secuencia de comandos .ps1 (o cualquier variante de la terminación del proceso que desea). Powershell continuará ejecutándose al final de la secuencia de comandos ya que no se le ha indicado que finalice (cuando se ejecuta en PS o ISE terminará automáticamente al final de la secuencia de comandos, pero no cuando se ejecuta a través del shell de DOS).

9

Tuvimos un problema similar. Quisimos llamar a una aplicación PowerShell de una pieza de software que acaba de tener una caja para introducir "Comando" y "Parámetros", pero aunque el PowerShell funcionó con éxito (pude ver el archivo afectado actualiza.)

finalmente, mi compañero de trabajo ayudó a resolverlo comando debe ser:

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe 

y parámetros:

-ExecutionPolicy unrestricted -Command "& {C:\scripts\apps\EDI\Test.ps1; [Environment]::Exit(1)}" 

En nuestro caso fue importante usar [Environment]::Exit(1) en lugar de Exit 1. Creo que Exit simplemente finalizó la secuencia de comandos, no cerrando Powershell sí mismo.

+1

Gracias por esta respuesta. Esto resolvió un problema que tenemos al usar el servidor de agentes de bambú y los scripts de Powershell. – Eddietec

+0

Gracias, trabajó también para mí, en lugar de tener "Salir" dentro del archivo ps1. – Pisu

+0

¡Genial! Tenía este problema en un servidor con PS2, y esto ha funcionado. Lo he agregado dentro de .ps1, y en lugar de '$ lastexitcode', puedo pasarlo lo que necesite. ¡Gracias! – curropar

Cuestiones relacionadas