¿Alguna vez has ejecutado un script o un cmdlet de PowerShell y te has enfrentado a un muro de texto gritando en rojo, como el que se muestra a continuación?

Los errores pueden volverse abrumadores y confusos. Y, sobre todo, los errores a menudo son difíciles de leer, lo que hace casi imposible determinar qué salió mal y dónde en el script.
Afortunadamente, tienes algunas opciones en PowerShell para mejorar esto a través del manejo de errores. Utilizando el manejo de errores, los errores se pueden filtrar y mostrar de tal manera que sea más fácil entenderlos. Y comprender el error facilita la adición de más lógica al manejo de errores.
En este artículo, aprenderás sobre los errores en PowerShell y cómo se pueden interceptar para realizar el manejo de errores utilizando los bloques Try Catch
(y finally
) de PowerShell.
Entendiendo cómo funcionan los errores en PowerShell
Antes de profundizar en el manejo de errores, cubramos primero algunos conceptos sobre errores en PowerShell. Comprender los errores puede llevar a mejores estrategias de manejo de errores.
La Variable Automática $Error
En PowerShell, hay muchas variables automáticas, y una de ellas es la variable automática $Error
. PowerShell utiliza la variable $Error
para almacenar todos los errores que se encuentran en la sesión. La variable $Error
es un conjunto de errores ordenados por los más recientes.
Cuando abres una sesión de PowerShell por primera vez, la variable $Error
está vacía. Puedes verificarlo llamando a la variable $Error
.

Como puedes ver, la variable $Error
comienza vacía. Pero, una vez que se genera un error, el error se agregará y almacenará en la variable $Error
.
En el ejemplo a continuación, el error se genera al obtener intencionalmente un nombre de servicio que no existe.

Como puedes ver en la salida anterior, el error generado se agregó a la variable $Error
.
La variable $Error contiene una colección de errores generados en la sesión de PowerShell. Cada error se puede acceder llamando a su posición en el arreglo. El último error siempre estará en el índice 0.
Por ejemplo, el último error se puede recuperar usando
$Error[0]
.
Las propiedades del objeto $Error
Dado que todo en PowerShell es un objeto, la variable $Error
es un objeto y los objetos tienen propiedades. Al pasar la variable $Error
al cmdlet Get-Member
, deberías ver la lista de propiedades disponibles.

Para determinar la razón del error, puedes ver el contenido de la propiedad InvocationInfo
usando el siguiente comando.

¡Ahora puedes hacer lo mismo con las otras propiedades y descubrir qué otra información puedes encontrar!
Errores terminantes
Errores terminales detienen el flujo de ejecución cuando son encontrados por PowerShell en comparación con los errores no terminales. Hay varias formas en que puede ocurrir un error terminal. Un ejemplo es cuando llamas a un cmdlet con un parámetro que no existe.
Como se puede ver en la captura de pantalla a continuación, cuando se ejecuta el comando Get-Process notepad
, el comando es válido y se muestran los detalles del proceso notepad.

Pero, cuando se utiliza un parámetro que no existe como Get-Process notepad -handle 251
, el cmdlet muestra un error indicando que el parámetro handle
no es válido. Luego, el cmdlet sale sin mostrar los detalles del proceso notepad
.

Errores No Terminales
Los errores no terminales son errores que no detienen la ejecución del script o comando. Por ejemplo, echa un vistazo al código a continuación. Este código obtiene la lista de nombres de archivo del archivo fileslist.txt. Luego, el script recorre cada nombre de archivo, lee el contenido de cada archivo y lo muestra en la pantalla.
El contenido del archivo filelist.txt son los nombres de archivo que se muestran en la lista a continuación.
Pero, ¿qué pasa si File_6.log en realidad no existe? Cuando ejecutas el código, esperarías que ocurra un error porque el script no puede encontrar el archivo File_6.log. Se mostrará una salida similar a la que se muestra a continuación.

Como puedes ver en la captura de pantalla del resultado anterior, el script pudo leer los primeros cinco archivos en la lista, pero cuando intentó leer el archivo File_6.txt, se produjo un error. Luego, el script continuó leyendo el resto de los archivos antes de salir. No terminó.
La Variable $ErrorActionPreference
Hasta ahora, has aprendido sobre los errores terminales y no terminales y cómo difieren entre sí. Pero, ¿sabías que se puede forzar a un error no terminal a que se trate como un error terminal?
PowerShell tiene un concepto llamado variables de preferencia. Estas variables se utilizan para cambiar el comportamiento de PowerShell de muchas maneras diferentes. Una de estas variables se llama $ErrorActionPreference
.
La variable $ErrorActionPreference
se utiliza para cambiar la forma en que PowerShell trata los errores no terminales. De forma predeterminada, el valor de $ErrorActionPreference
está configurado en Continue
. Cambiar el valor de la variable $ErrorActionPreference
a STOP
fuerza a PowerShell a tratar todos los errores como errores terminales.
Usa el siguiente código para cambiar el valor de $ErrorActionPreference
.
Para obtener más información sobre otros valores válidos de la variable $ErrorActionPreference, visita PowerShell ErrorActionPreference.
Ahora, vuelve al ejemplo utilizado en la sección de Errores no terminales en este artículo. El script se puede modificar para incluir el cambio en $ErrorActionPreference
como se muestra a continuación:
Al ejecutar el código modificado anteriormente, se comportará de manera diferente que antes cuando el valor de $ErrorActionPreference
se establece en el valor predeterminado de Continuar
.

$ErrorActionPreference
variableComo se puede ver en la captura de pantalla del resultado anterior, el script pudo leer los primeros cinco archivos en la lista, pero cuando intentó leer el archivo File_6.txt, se devolvió un error porque no se encontró el archivo. Luego, el script se terminó y no se leyeron el resto de los archivos.
El valor de
$ErrorActionPreference
solo es válido en la sesión actual de PowerShell. Se restablece al valor predeterminado una vez que se inicia una nueva sesión de PowerShell.
El parámetro común ErrorAction
Si se aplica el valor de $ErrorActionPreference
a la sesión de PowerShell, el parámetro ErrorAction
se aplica a cualquier cmdlet que admita parámetros comunes. El parámetro ErrorAction
acepta los mismos valores que la variable $ErrorActionPreference
.
El valor del parámetro ErrorAction
tiene prioridad sobre el valor de $ErrorActionPreference
.
Volviendo al mismo código del ejemplo anterior, pero esta vez, se agrega el parámetro ErrorAction
a la línea Get-Content
.
Después de ejecutar el código modificado, verás que aunque $ErrorActionPreference
está configurado en Continue
, el script aún se termina cuando encuentra un error. Esto ocurre porque el valor del parámetro ErrorAction
en Get-Content
está configurado en STOP
.

ErrorAction
parameterUso de bloques Try Catch en PowerShell
En este punto, has aprendido sobre los errores de PowerShell y cómo funcionan la variable $ErrorActionPreference
y los parámetros ErrorAction
de PowerShell. Ahora es el momento de aprender sobre lo bueno: los bloques Try Catch Finally
de PowerShell.
Los bloques try catch
de PowerShell (y el bloque opcional finally
) son una forma de envolver un fragmento de código y capturar cualquier error que se produzca.
El código a continuación muestra la sintaxis de la declaración Try
.
El bloque Try
contiene el código que deseas que PowerShell “intente” y supervise en busca de errores. Si el código en el bloque Try
encuentra un error, este se agrega a la variable $Error
y luego se pasa al bloque Catch
.
El bloque Catch
contiene las acciones a ejecutar cuando recibe un error del bloque Try
. Puede haber varios bloques Catch
en una declaración Try
.
El bloque Finally
contiene el código que se ejecutará al final de la declaración Try
. Este bloque se ejecuta independientemente de si se encontró un error o no.
Capturando errores no específicos (Catch-All) con ErrorAction de PowerShell
A simple Try
statement contains a Try
and a Catch
block. The Finally
block is optional.
Por ejemplo, para capturar una excepción no específica, el parámetro Catch
debe estar vacío. El código de ejemplo a continuación está utilizando el mismo script que se usó en la sección La Variable $ErrorActionPreference pero modificado para usar los bloques Try Catch
.
Como puedes ver en el código a continuación, esta vez, la instrucción foreach
está encerrada dentro del bloque Try
. Luego, un bloque Catch
contiene el código para mostrar la cadena Se produjo un error
si ocurriera un error. El código en el bloque Finally
simplemente borra la variable $Error
.
El código anterior, después de ejecutarse en PowerShell, te dará esta salida que se muestra a continuación.

La salida anterior muestra que el script encontró un error, ejecutó el código dentro del bloque Catch
y luego terminó.
El error fue manejado, que era el propósito del manejo de errores. Sin embargo, el error mostrado fue demasiado genérico. Para mostrar un error más descriptivo, podrías acceder a la propiedad Exception
del error que fue pasado por el bloque Try
.
El código a continuación está modificado, específicamente el código dentro del bloque Catch
, para mostrar el mensaje de excepción del error actual que fue pasado por la canalización – $PSItem.Exception.Message
Esta vez, cuando se ejecuta el código modificado anterior, el mensaje mostrado es mucho más descriptivo.

Capturando Errores Específicos
Hay momentos en los que un manejo de errores generalizado no es el enfoque más apropiado. Quizás quieras que tu script realice una acción que dependa del tipo de error que se encuentre.
¿Cómo determinas el tipo de error? Revisando el valor TypeName
de la propiedad Exception
del último error. Por ejemplo, para encontrar el tipo de error del ejemplo anterior, usa este comando:
El resultado del código anterior se vería como la captura de pantalla a continuación. Como puedes ver, se muestra el valor TypeName
– System.Management.Automation.ItemNotFoundException
.

Ahora que conoces el tipo de error que necesitas interceptar, modifica el código para capturarlo de manera específica. Como ves en el código modificado a continuación, ahora hay dos bloques Catch
. El primer bloque Catch
intercepta un tipo específico de error (System.Management.Automation.ItemNotFoundException
). En contraste, el segundo bloque Catch
contiene el mensaje de error genérico que atrapa cualquier tipo de error.
La captura de pantalla a continuación muestra la salida del código modificado anteriormente.

Conclusión
En este artículo, has aprendido sobre los errores en PowerShell, sus propiedades y cómo puedes determinar el tipo específico de un error. También has aprendido la diferencia entre cómo la variable $ErrorActionPreference
y el parámetro ErrorAction
de PowerShell afectan la forma en que PowerShell trata los errores no terminales.
También has aprendido cómo utilizar los bloques Try Catch Finally
de PowerShell para realizar el manejo de errores, ya sea para errores específicos o de enfoque general.
Los ejemplos que se muestran en este artículo solo demuestran lo básico de cómo funcionan los bloques Try Catch Finally
. El conocimiento que espero que hayas adquirido en este artículo debería proporcionarte las bases para comenzar a aplicar el manejo de errores en tus scripts.