2010-12-08 25 views
6

Tengo un montón de scripts que se ejecutan como tareas programadas. Entonces hacen un $host.setshouldexit(1) en cualquier falla, que aparece en el planificador de tareas como el código de retorno.Cómo devolver un código de salida de un script de Powershell solo cuando se ejecuta de forma no interactiva

También quiero ser capaz de ejecutar estos scripts interactivamente mientras se depuran y prueban. Entonces, el $host.setshouldexit() mata mi sesión powershell o ISE.

Mi pregunta es: ¿cómo puedo detectar si un script se ejecuta de forma no interactiva? Si es así, entonces usaré setshouldexit, de lo contrario, se imprimirá el código de error o algo no destructivo. (Tenga en cuenta que no quiero utilizar [environment]::userinteractive porque estos scripts no siempre se ejecutan en lo que el sistema operativo piensa que es una sesión no interactiva.)

Existe un interruptor no interactivo que estoy usando para las tareas programadas . ¿Hay alguna forma de que pueda consultar eso desde PowerShell?

Respuesta

6

El método $Host.SetShouldExit no debería ser necesario, y es realmente inconsistente, dependiendo de cómo llame a sus scripts. Con la palabra clave exit debe obtener su estado de salida.

Usando powershell -F script.ps1:

  • exit - funciona
  • SetShouldExit - ignorado

Usando powershell -c '.\script.ps1:

  • exit - Estado reduce a 0 o 1, para el éxito o el fracaso del guion, respe ctivamente.
  • SetShouldExit - sale con el estado correcto, pero las líneas restantes en el script todavía se ejecutan.

Usando powershell -c '.\script.ps1; exit $LASTEXITCODE [1]:

  • exit - obras
  • SetShouldExit - termina con un estado == 0, y las líneas de guión todavía se ejecutan restante.

llamadas directamente desde powershell (> .\script.ps1):

  • exit - obras
  • SetShouldExit - termina llamando anfitrión PowerShell con el código de salida dada
2

¿Por qué no simplemente tomar un parámetro "prueba" que establece el comportamiento correcto durante sus pruebas? Tienes un búfer de historial por lo que difícilmente tendrás que tipear para ejecutarlo.

+0

Hmm, eso no es tan malo. Me lo llevo. – scobi

2

Tuve el mismo problema. Las siguientes obras para mí:

# Exit with Return Code when NOT using PowerShell ISE 
if ($psise -eq $Null) 
{ 
    $host.SetShouldExit(1) 
} 
+2

Hay más shells que ISE que son interactivos. – scobi

2

Al encontrar su pregunta me han tomado el asunto un poco más y se encontró $MyInvocation.MyCommand.Name. Esto es falso tanto en el intérprete de comandos como en el intérprete de comandos ISE. Y cuando un script (el mío es jest.ps1) que contiene sólo la línea: Write-Host $MyInvocation.MyCommand.Name se ejecuta desde la llamada a cmd.exe PowerShell.exe como:

%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy RemoteSigned -NoExit -NonInteractive -NoProfile -File "M:\WindowsPowerShell\Jest.ps1" 

salida es simplemente:

Jest.ps1

+0

Y, por cierto, gracias por el uso de $ host.SetShouldExit (1)! – Stef

+0

El código en línea está marcado con patillas ('), los bloques de código se marcan al sangrar cada línea con 4 espacios. Consulte las [Preguntas frecuentes sobre la edición] (http://stackoverflow.com/editing-help#comment-formatting). –

1

Comprobar $ Host.Name. Si su script se ejecuta fuera de un IDE, devolverá un valor de "ConsoleHost". De lo contrario, devolverá una referencia al IDE como "Host de Windows PowerShell ISE" o "PowerGUIScriptEditorHost".

Tengo que usar SetShouldExit porque el programador que ejecuta mis scripts por lo general ignora otros métodos para indicar una falla. Agrego una función para permitir SetShouldExit cuando $ Host.Name es "ConsoleHost". Se ahorra una gran cantidad de bloqueos IDE durante las pruebas.

+0

Cuando un script se ejecuta como un trabajo, $ Host.Name es igual a "ServerRemoteHost" (probado en PS v5). –

Cuestiones relacionadas