Cómo usar Try, Catch, Finalmente en PowerShell

Los errores en su secuencia de comandos de PowerShell pueden detener la ejecución de su secuencia de comandos, pero a veces eso es completamente innecesario.

Pruebe los bloques Catch en PowerShell ayudarlo a manejar esos errores correctamente.

Tome el siguiente ejemplo; Debe actualizar los títulos de trabajo de 20 empleados. El departamento de recursos humanos le ha dado una lista con los nombres y los nuevos títulos de trabajo, pero escribieron mal uno de los nombres.

Sin un bloque Try Catch de PowerShell, su secuencia de comandos se detendría en algún lugar en el medio, dejándolo con la mitad de los registros actualizados. Ahora deberá averiguar dónde se detuvo el script y qué usuario provocó el error.

Con Try Catch en PowerShell, podemos procesar toda la lista y escribir un mensaje de error adecuado (o incluso enviar un correo electrónico) cuando algo anda mal.

En este artículo, vamos a echar un vistazo a cómo usar Prueba, Captura, Finalmente en PowerShell y cómo encontrar el mensaje de error correcto para capturar.

Powershell Intenta atrapar finalmente

Primero echemos un vistazo a los conceptos básicos del bloque Try Catch Finalmente.

Siempre existe un bloque Try Catch en Powershell de uno Prueba bloquear y al menos una captura bloquear, los Finalmente el bloque es opcionalel código de este bloque siempre se ejecutará, sin importar el resultado del bloque Try.

Try
{
    # Try something that could cause an error
    1/0
}
Catch
{
    # Catch any error
    Write-Host "An error occurred"
}
Finally
{
    # [Optional] Run this part always
    Write-Host "cleaning up ..."
}

En el bloque Try, coloca el script que podría causar un error. Mantenga esta parte pequeña y no combine demasiadas funciones en ella.

El objetivo con un bloque Try Catch de PowerShell es implementar un manejo de errores adecuado, y solo puede hacerlo cuando Pruebe una función complicada a la vez.

Si tomamos el siguiente ejemplo (simplificado) para actualizar los títulos de trabajo:

Try{
	# Find the user to update
	$ADUser = Get-AzureAdUser -SearchString $user.name

	# Update the job title
	Set-AzureAdUser -ObjectId $ADUser.ObjectId -JobTitle $user.jobtitle

	# Send an email that the job title is updated
	Send-MailMessage -SmtpServer $smtp.address -To $user.mail -From $smtp.from -Subject $smtp.subject -Body "Your jobtitle is updated"
}
Catch{
	Write-Host ("Failed to update " + $($user.name)) -ForegroundColor Red
}

El problema aquí es que si algo sale mal en el bloque Try, solo obtenemos un error de que la actualización falló. Pero no sabes qué parte. Tal vez el usuario esté actualizado pero el script no pudo enviarse al correo.

Una mejor opción aquí es dividir Try para encontrar y actualizar al usuario y crear otra función con Try-Catch para enviar el correo electrónico.

PowerShell finalmente bloque

El bloque finalmente es opcional, por lo que no necesita usarlo cada vez. El código dentro del bloque finalmente siempre se ejecuta, sin importar el resultado del bloque Try.

Puede usar el bloque finalmente para cerrar una conexión, por ejemplo, o como parte de su registro.

Captura de errores de terminación y no terminación

Cuando se trata de detectar errores en PowerShell, hay una cosa realmente importante, errores de no terminación.

Estos son errores que no terminarán (detendrán) el script. Este tipo de errores no se pueden detectar con un bloque catch de forma predeterminada.

La mayoría de los cmdlets en PowerShell no terminan. Emitirán un error, que verá en rojo en su consola, si los usa incorrectamente, pero no detendrán el script.

La razón de esto es el valor predeterminado. ErrorAcción en su perfil de PowerShell, que está configurado para Continuar.

# To show your default error action type
$ErrorActionPreference

Tome el siguiente ejemplo, abriendo un directorio no existente en PowerShell con un bloque Try Catch:

Try {
    dir "c:\some\non-existing\path"
    
}
Catch {
    Write-host "Directory does not exist"
}

Espera ver «El directorio no existe», pero en su lugar recibe el mensaje de error rojo normal.

La razón de esto es que la ruta inexistente no es un error de finalización y la acción de error predeterminada es continuar.

Para detectar el error, deberá agregar el -ErrorAction Stop parámetro detrás de su acción.

Try {
    dir "c:\some\non-existing\path" -ErrorAction stop
    
}
Catch {
    Write-host "Directory does not exist"
}

Otra opción es cambiar ErrorActionPreference al comienzo de su secuencia de comandos o sesión de PowerShell. Pero tenga en cuenta que la preferencia se restablecerá para continuar cuando inicie una nueva sesión.

$ErrorActionPreference = "Stop"

Powershell prueba la excepción de captura

Las excepciones en PowerShell le permiten manejar los errores aún mejor. Hasta ahora, solo usamos una captura simple, que básicamente detectará cualquier error.

Es una buena manera de comenzar, pero si desea mejorar aún más el manejo de errores de PowerShell, puede usar Excepciones.

Como mencioné al principio, un bloque Try Catch debería tener al menos un bloque de captura.

Eso significa que podemos tener múltiples bloques catch para detectar diferentes errores y manejarlos de manera diferente.

Si tomamos el siguiente ejemplo con la actualización de los títulos de trabajo:

Try{
	# Find the user to update
	$ADUser = Get-AzureAdUser -ObjectId $user.UserPrincipalName -ErrorAction Stop

	# Update the job title
	Set-AzureAdUser -ObjectId $ADUser.ObjectId -JobTitle $user.jobtitle -ErrorAction Stop
}
Catch [Microsoft.Open.Azure.AD.CommonLibrary.AadNeedAuthenticationException]{
	# Catch a connection error
	Write-Warning "You need to Connect to AzureAD first"
}
Catch [Microsoft.Open.AzureAD16.Client.ApiException] {
	# Catch the when we are unable to find the user
	Write-Warning "Unable to find the user"
}
Catch {
	Write-Warning "An other error occured"
}

Lo que podemos hacer aquí, por ejemplo, detectar el error cuando la conexión a AzureAD aún no se ha realizado, o el error cuando no podemos encontrar al usuario en AzureAD. Hacemos esto definiendo una excepción a un bloque catch.

La parte difícil aquí es encontrar la excepción que tienes que atrapar. La única forma de encontrarlos es ejecutar su secuencia de comandos y asegurarse de activar el error que desea detectar. A

continuación, puede encontrar la excepción en el mensaje de error o en el $Error variable

powershell intenta atrapar

Como puede ver en la captura de pantalla, podemos encontrar la excepción de autenticación en el mensaje de error (1).

Otra opción es echar un vistazo a la variable $Error. Si corres $Error[0].Exception.GetType().FullName directamente después del error, obtendrá el nombre completo de la excepción que puede usar en el bloque catch.

Variable de error de Powershell

Expliquemos un poco más sobre la variable Error de PowerShell. Cuando ocurre un error en PowerShell, se agregará al $error variable. Esta variable contendrá todos los errores que ocurrieron durante su sesión de PowerShell.

En lugar de $error, también puedes usar ps o $PSitem dentro del bloque catch para mostrar detalles sobre el error.

La variable $error es realmente útil y contiene mucha información sobre el error. No solo podemos usar esta información para manejar el error correctamente, sino también para informar mejor al usuario.

Encontrar la ubicación del error

Cuando está escribiendo un script más grande, es útil conocer la ubicación exacta de la función que causa el error. En la variable de error, encontrará el ScriptStackTrace. Esto generará la ubicación exacta del error y el origen.

Tome el siguiente ejemplo:

$ErrorActionPreference = "Stop"


Function OpenPath($path) {
    Try {
        dir $path 
    }
    Catch {
        Write-host "Directory does not exist" -ForegroundColor Red
        Write-Host $_.ScriptStackTrace
    }
}

OpenPath("c:\some\non-existing\path")

Cuando ejecute este código, obtendrá el siguiente seguimiento de la pila:

powershell intente capturar el manejo de errores

Como puede, el error ocurrió en la línea 6, en la función OpenPath, que fue llamada por el script en la línea 15.

Este tipo de información realmente puede ayudarlo a depurar sus scripts.

Mostrar mensajes de error adecuados

Puede escribir sus propios mensajes de error en los bloques Catch de PowerShell, pero a veces los mensajes de excepción son más que suficientes.

Function OpenPath($path) {
    Try {
        dir $path -ErrorAction Stop
    }
    Catch {
        Write-Host $_.Exception.Message -ForegroundColor Red
    }
}

#Outputs:
Cannot find path 'C:\some\non-existing\path' because it does not exist.

Errores de cálculo en PowerShell

Una pequeña característica de la variable Error, pero en algún momento realmente útil, contando cuántos errores ocurrieron

$Error.count

Borrado de la variable de error de PowerShell

La variable de error contiene mucha información, puede ver todas las propiedades de la variable de error mediante el cmdlet get-member.

Lo último que quiero señalar es borrar la variable de error. Cuando intenta encontrar la excepción correcta, es realmente útil borrar la variable antes de ejecutar su secuencia de comandos nuevamente.

$Error.clear()

Terminando

Pruebe los bloques Catch en PowerShell que lo ayudan a escribir mejores secuencias de comandos, secuencias de comandos que hacen lo que desea, incluso si algo sale mal.

La parte más difícil es escribir buenos bloques de captura, porque necesitará descubrir qué es lo que puede salir mal con su secuencia de comandos.

Espero que este artículo te haya ayudado a comenzar con los bloques Try-Catch, si tienes alguna pregunta, solo deja un comentario a continuación.

Otros artículos relacionados

Personalizando la nueva Terminal de Windows

Personalizando la nueva Terminal de Windows

Normalmente empiezo un nuevo año limpiando mi escritorio, deshaciéndome de toda la basura que guardé en él durante los últimos ...
Leer Más
Guía y scripts de desinstalación, reinstalación y limpieza de Microsoft Teams

Guía y scripts de desinstalación, reinstalación y limpieza de Microsoft Teams

Microsoft Teams no es como un programa promedio cuando se trata de instalarlo y desinstalarlo. El problema con Microsoft Teams ...
Leer Más
Obtenga el informe de métricas de almacenamiento de OneDrive con PowerShell

Obtenga el informe de métricas de almacenamiento de OneDrive con PowerShell

¿Sabe cuánto almacenamiento de OneDrive utilizan sus usuarios? Probablemente no, y en la mayoría de los casos, tampoco importa. Obtienen ...
Leer Más
Obtener AzureADUser: cómo encontrar usuarios de Azure AD con PowerShell

Obtener AzureADUser: cómo encontrar usuarios de Azure AD con PowerShell

Al igual que con Active Directory local, podemos administrar nuestros usuarios en Azure AD con PowerShell. Para esto, necesitaremos usar ...
Leer Más
Cómo exportar a un archivo con PowerShell Out-File

Cómo exportar a un archivo con PowerShell Out-File

La salida de los comandos de PowerShell se muestra de forma predeterminada en el terminal. Pero en algunas situaciones, es ...
Leer Más
Los 10 principales comandos de PowerShell que debe conocer

Los 10 principales comandos de PowerShell que debe conocer

PowerShell es realmente poderoso y puede hacer que su trabajo diario sea mucho más fácil. Con todos los módulos que ...
Leer Más

Deja un comentario