windows - ejemplos - ¿Cómo detener una secuencia de comandos de PowerShell en el primer error?
ejecutar ps1 desde cmd (5)
Debería poder lograr esto usando la declaración $ErrorActionPreference = "Stop"
al comienzo de sus scripts.
La configuración predeterminada de $ErrorActionPreference
es Continue
, razón por la cual está viendo que sus scripts continúan después de que se producen errores.
Quiero que mi script de PowerShell se detenga cuando falla alguno de los comandos que ejecuto (como set -e
en bash). Estoy usando ambos comandos Powershell ( New-Object System.Net.WebClient
) y programas ( ./setup.exe
).
Lamentablemente, debido a los cmdlets con errores como New-RegKey y Clear-Disk , ninguna de estas respuestas es suficiente. 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 llamadas nativas 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, así que las sugerencias son bienvenidas.
Necesita un manejo de errores ligeramente diferente para las funciones de PowerShell y para llamar a los ejecutables, y debe asegurarse de decirle a la persona que llama del script que ha fallado. Sobre la base de Exec
de la biblioteca Psake, una secuencia de comandos que tiene la siguiente estructura se detendrá en todos los errores y se puede utilizar como una plantilla base para la mayoría de las secuencias de comandos.
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
}
Vine aquí buscando lo mismo. $ ErrorActionPreference = "Parar" mata mi caparazón inmediatamente cuando prefiero ver el mensaje de error (pausa) antes de que finalice. Volviendo a la sensibilidad de mi lote:
IF %ERRORLEVEL% NEQ 0 pause & GOTO EOF
Descubrí que esto funciona más o menos igual para mi script ps1 particular:
Import-PSSession $Session
If ($? -ne "True") {Pause; Exit}
$ErrorActionPreference = "Stop"
te llevará a una parte del camino (es decir, esto funciona muy bien para los cmdlets).
Sin embargo, para los EXEs, deberá verificar $LastExitCode
usted mismo después de cada invocación a un exe y determinar si falló o no. Lamentablemente, no creo que PowerShell pueda ayudar aquí porque en Windows, los EXE no son muy 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. Consulte la función CheckLastExitCode en esta publicación de blog . Tu podrias encontrar esto útil.