¿Cómo detener un script de PowerShell en el primer error?


Quiero que mi script de PowerShell se detenga cuando cualquiera de los comandos que ejecute falle (como set -e en bash). Estoy usando tanto comandos de Powershell (New-Object System.Net.WebClient) como programas (.\setup.exe).

Author: Joey, 2012-03-30

5 answers

$ErrorActionPreference = "Stop" le llevará parte del camino allí (es decir, esto funciona muy bien para cmdlets).

Sin embargo, para EXEs, necesitará verificar $LastExitCode usted mismo después de cada invocación de exe y determinar si eso falló o no. Desafortunadamente, no creo que PowerShell pueda ayudar aquí porque en Windows, los EXEs no son terriblemente consistentes en lo que constituye un código de salida de "éxito" o "error". La mayoría sigue el estándar UNIX de 0 indicando éxito, pero no todos lo hacen. Echa un vistazo al CheckLastExitCode función en esta entrada del blog. Puede que te resulte útil.

 210
Author: Keith Hill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-22 20:03:50

Debería ser capaz de lograr esto usando la instrucción $ErrorActionPreference = "Stop" al principio de sus scripts.

La configuración predeterminada de $ErrorActionPreference es Continue, por lo que está viendo que sus scripts siguen funcionando después de que ocurran errores.

 57
Author: goric,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-30 19:11:09

Lamentablemente, debido a cmdlets con errores como New-RegKey y Clear-Disk , ninguna de estas respuestas son suficientes. Actualmente me he decidido por las siguientes líneas en la parte superior de cualquier script de Powershell para mantener mi cordura.

Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
$PSDefaultParameterValues['*:ErrorAction']='Stop'

Y luego cualquier llamada nativa recibe este tratamiento:

native_call.exe
$native_call_success = $?
if (-not $native_call_success)
{
    throw 'error making native call'
}

Ese patrón de llamada nativo se está volviendo lo suficientemente común para mí que probablemente debería buscar opciones para hacerlo más conciso. Todavía soy un novato de Powershell, por lo que las sugerencias son bienvenidas.

 7
Author: aggieNick02,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-28 19:21:47

Necesita un manejo de errores ligeramente diferente para las funciones de powershell y para llamar a exe, y debe asegurarse de decirle a la persona que llama de su script que ha fallado. Construyendo encima de Exec desde la biblioteca Psake, un script que tiene la estructura de abajo se detendrá en todos los errores, y se puede usar como plantilla base para la mayoría de los scripts.

Set-StrictMode -Version latest
$ErrorActionPreference = "Stop"


# Taken from psake https://github.com/psake/psake
<#
.SYNOPSIS
  This is a helper function that runs a scriptblock and checks the PS variable $lastexitcode
  to see if an error occcured. If an error is detected then an exception is thrown.
  This function allows you to run command-line programs without having to
  explicitly check the $lastexitcode variable.
.EXAMPLE
  exec { svn info $repository_trunk } "Error executing SVN. Please verify SVN command-line client is installed"
#>
function Exec
{
    [CmdletBinding()]
    param(
        [Parameter(Position=0,Mandatory=1)][scriptblock]$cmd,
        [Parameter(Position=1,Mandatory=0)][string]$errorMessage = ("Error executing command {0}" -f $cmd)
    )
    & $cmd
    if ($lastexitcode -ne 0) {
        throw ("Exec: " + $errorMessage)
    }
}

Try {

    # Put all your stuff inside here!

    # powershell functions called as normal and try..catch reports errors 
    New-Object System.Net.WebClient

    # call exe's and check their exit code using Exec
    Exec { setup.exe }

} Catch {
    # tell the caller it has all gone wrong
    $host.SetShouldExit(-1)
    throw
}
 3
Author: alastairtree,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-27 00:07:49

Vine aquí buscando lo mismo. Er ErrorActionPreference = "Stop" mata mi shell inmediatamente cuando prefiero ver el mensaje de error (pausa) antes de que termine. La caída de nuevo en mi lote sensibilidades:

IF %ERRORLEVEL% NEQ 0 pause & GOTO EOF

Descubrí que esto funciona prácticamente igual para mi script de ps1 en particular:

Import-PSSession $Session
If ($? -ne "True") {Pause; Exit}
 1
Author: harvey263,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-01 21:41:07