windows - desinstalar - La secuencia de comandos de Powershell se atasca, no sale cuando se llama desde un archivo de proceso por lotes
windows powershell vs cmd (10)
Desde mi experiencia, PowerShell.exe puede ejecutar fácilmente scripts desde un archivo de proceso por lotes o un script de shell de forma predecible utilizando el modificador de archivo. No es necesario usar el comando de Inicio.
Lo importante es agregar
< nul
a la línea de comando desde dentro de un archivo por lotes. Mi investigación ha demostrado que PowerShell ejecuta los comandos en el script indicado a través del modificador de archivo y luego espera comandos adicionales de PowerShell a partir de la entrada estándar (mi breve experimentación con el conmutador de comando 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.
Al invocar PowerShell desde Cygwin, use
< /dev/null
Por ejemplo, he ejecutado scripts de PowerShell de Cygwin usando variables de shell, como esta:
PowerShell.exe -ExecutionPolicy RemoteSigned -File $_powershellscriptpath $_firstscriptparameter < /dev/null
Por favor, publique un comentario si su experiencia varió de la mía. - Gordon
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 proceso de importación está incrustado en un script que es ejecutado por un programa de terceros llamado scriptFTP .
La secuencia de comandos funciona bien cuando lo llamo desde un solo archivo .bat, así:
powershell "& "C:/data/etc/run_import_script.ps1"
exit %ERRORLEVEL%
Sin embargo, cuando llamo a este archivo .bat desde el contexto de ScriptFTP mayor, 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 del script 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%
funciona , ejecuta el script de PowerShell en una consola nueva, pero no puedo tomar el nivel de error que devuelve PowerShell.
Intenté llamar directamente a PowerShell desde ScriptFTP, omitiendo el archivo por lotes, pero con el mismo resultado: simplemente se bloquea.
Cualquier salida que tenga el script de PowerShell con Write-Output
o Write-Host
no se muestra.
Todos los programas se ejecutan bajo el mismo usuario, yo.
¿Alguien tiene alguna idea de qué hacer?
El problema que apuesto es que el proceso de Powershell continúa ejecutándose 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.
Esta variante podría funcionar para ti.
powershell -NoProfile -Command "C:/data/etc/run_import_script.ps1; exit $LASTEXITCODE" < NUL
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"
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 -see powershell.exe /? para obtener información adicional.
C:/>powershell "''Hello''"
Hello
Lo que tendrá que hacer es construir una cadena de entrada inteligente para "generar" el script que desea ejecutar:
C:/>powershell ". ./test.ps1"
Hello, World!
En cuanto a la salida, una vez que el script se ejecuta correctamente, debería ser solo 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!"
Invoca el comando:
test.bat > test.txt
Y verifica que la salida fue capturada:
C:/>type test.txt
Hello, World!
SI eso es exactamente lo que está en su archivo es porque tiene citas que no coinciden. Powershell está esperando la última cita.
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 de proceso 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 el process.Kill()
para forzar a PowerShell a que se cierre, encendimos el uso de START /WAIT /B PowerShell.exe ..
No tengo idea de por qué esto debería funcionar, pero lo hace ...
Tenía el problema exacto, intentábamos integrar los scripts de 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á integrado 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
Tuvimos un problema similar. Queríamos llamar a una aplicación de PowerShell desde un programa que solo tenía un cuadro para ingresar a "Comando" y "Parámetros", pero aunque PowerShell se ejecutó correctamente (pude ver el archivo afectado actualizado).
Finalmente mi compañero de trabajo me ayudó a resolverlo. El 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, era importante usar [Environment]::Exit(1)
lugar de la Exit 1
. Creo que Exit simplemente terminó el script, no cerrando Powershell .
simplemente puede agregar un comando ''exit'' al final del script .ps1 (o cualquier variante de terminación del proceso que desee). 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).