Como su nombre indica, PowerShell es mucho más potente que el símbolo del sistema estándar de Windows. Con ese poder viene una mayor posibilidad de errores confusos. Si su secuencia de comandos falla de repente, es posible que no sepa por dónde empezar a buscar lo que ha fallado. Aquí es donde el manejo de errores de PowerShell es útil.
Si estás familiarizado con otros lenguajes, probablemente conozcas los fundamentos del manejo de errores, pero hay algunos aspectos específicos de PowerShell que necesitarás conocer. Hay cuatro partes para el manejo de errores en PowerShell: el parámetro Acción de error, los bloques Try/Catch, el parámetro Variable de error y el registro.
Manejo de errores en PowerShell de manera fácil
El primer paso en el manejo de errores en PowerShell es lidiar con algo que detiene su secuencia de comandos en sus pistas. Si el fallo no afecta al resto de su script, podría ser mejor simplemente decirle a PowerShell que ignore los errores y seguir adelante.
Por otro lado, no siempre está claro cuando un determinado cmdlet lanza un error de terminación. Algunos cmdlets devuelven un error pero no detienen su script. Esto podría dejarle esperando a que su script se complete mientras se producen salidas sin sentido.
Aquí es donde entra el parámetro -ErrorAction. Se utiliza para forzar un cmdlet para manejar el error de la manera que usted desea. Si estás modificando un script existente, lo añades al final de la línea del cmdlet.
Get-ChildItem -Path "~\Documents\*.jpg" -Recurse -ErrorAction Stop
Obviamente, si está utilizando el cmdlet Get-ChildItem por sí mismo, este error no le sirve de mucho. Sin embargo, si quieres hacer algo con los datos, sería bueno detener el script, para saber que la búsqueda falló y por qué. Alternativamente, si está haciendo múltiples búsquedas, cambie el parámetro de Stop a SilentlyContinue, para que el script continúe si una búsqueda falla. Si quieres ver cuál es el error, puedes usar Continue como parámetro en su lugar.
Get-ChildItem -Path "~\Documents\*.jpg" -Recurse -ErrorAction SilentlyContinue
Si prefiere tener la opción de controlar lo que sucede cada vez que su script se ejecuta, puede cambiarlo a Inquire. Cuando su cmdlet encuentra un obstáculo, da opciones: Sí, Sí Para Todos, Detener Comando, Suspender o Ayuda.
Esta opción es un poco más flexible pero significa que los errores hacen que su script espere su entrada. Eso está bien si estás usando PowerShell para enviar un correo electrónico o alguna otra tarea simple, pero podría no ser algo que quieras cuando estás ejecutando un proceso largo durante la noche.
Manejo de errores de PowerShell de la manera poderosa
El parámetro ErrorAction aborda sus errores de una manera poco complicada. Sin embargo, si usted está buscando un poco más de control sobre los errores, PowerShell todavía tiene cubierto. Usando Try/Catch, ahora podemos bifurcar el script cuando los cmdlets devuelven un error.
Como el nombre sugiere, Try/Catch se compone de dos partes. (Hay técnicamente una tercera, pero llegaremos a eso en un minuto). La primera es la sección Try. Vas a ejecutar tu código normal en esta sección. Todavía va a utilizar el parámetro -ErrorAction, pero sólo puede establecerse como Stop. Esta bandera asegura que su cmdlet desencadena el Catch—incluso si no tiene un error de terminación.
Try{
Get-Process "Cortana" -ErrorAction Stop
}
Try también puede impedir que se ejecuten otros cmdlets si la búsqueda falla. En este caso, si estaba enviando los resultados de Get-Process a Stop-Process, una búsqueda fallida impide que se ejecute el segundo cmdlet.
Así que ahora que has creado un bloque try de cmdlets, ¿qué quieres hacer cuando falle? Usando el medio Catch, vas a definir esto.
Catch{
Write-Host "Process Not Found"
}
Al igual que con el parámetro ErrorAction, cuando estás haciendo algo un poco más complejo Catch será útil para algo más que dar un fallo en lenguaje llano, especialmente cuando estás haciendo algo un poco más complejo. (En el ejemplo anterior, el fallo es forzado al usar el nombre de la aplicación, y no el nombre del proceso). Así que asegúrate de jugar con el bloque Try para crear la búsqueda/acción que necesitas. Puedes usar el bloque Catch para que tu script te envíe un correo electrónico si falla.
La tercera parte es útil si quieres que algo se ejecute independientemente de si tu cmdlet tiene éxito o no. Para ello, puedes utilizar el bloque Finally. Lo añades después de Try y Catch y lo registras cuando una sección de tu script termina.
La variable de error y el registro
Su script ahora controla cómo maneja los errores y cómo responde a ellos. Puede utilizarlo como una tarea programada, o al menos ejecutarlo cuando no esté en su escritorio. Sin embargo, ¿cómo puede investigar un script fallido? Con el parámetro -ErrorVariable los errores de su cmdlet escriben en una variable personalizada.
Esta es una alternativa a la variable $Error del sistema, que contiene todos los errores de la sesión actual.
Tu cmdlet necesita ser un poco más largo. Primero, define una variable, algo como $SearchError servirá para el ejemplo. Cuando llamas a SearchError en el parámetro ErrorVariable, no usas el signo de dólar.
Aunque estés llamando a una variable que has creado, debido a la forma en que funciona el parámetro lo llamas sin el signo de dólar. Entonces añade eso al final de la línea.
Get-ChildItem -Path "~\Documents\*.jpg" -Recurse -ErrorAction Continue -ErrorVariable SearchError
Si añades un + delante del nombre de la variable, puedes añadir a la variable en lugar de reemplazarla directamente. Esto le da el mismo comportamiento que la variable de error global. En lugar de eso, puedes usar esta salida y Try/Catch para escribir una salida personalizada, y ponerle un sello de tiempo.
Para que esto funcione, cree un archivo de texto justo después de establecer la variable de error. Hágalo con el cmdlet New-Item. Puede utilizar la opción Inquire para el parámetro ErrorAction. Esto le permite añadir a un registro existente cuando el cmdlet New-Item falla.
$SearchLog = New-Item "~\SearchLog.txt" -type file -ErrorAction Inquire
Ahora, cuando construya su bloque Try/Catch, puede utilizar el Catch para registrar en un archivo de texto. Utilice Get-Date para crear la marca de tiempo. El formato puede ser complicado, así que asegúrese de copiarlo del ejemplo.
Try{
Get-ChildItem -Path "~\Documents\*.jpg" -Recurse -ErrorAction Stop -ErrorVariable SearchError
}
Catch{
Add-Content -Path $SearchLog -Value "$(Get-Date -Format dd-MM-yy-hh_mm_ss) Files not found returned error: $SearchError"
}
Repita esto como sea necesario para todos sus cmdlets, y ahora tiene un buen registro de cualquier error. Si quieres hacer un seguimiento de las cosas que se ejecutan con éxito puedes añadir un Add-Content similar al final del bloque Try.
Este registro sólo se ejecuta cuando su cmdlet Try tiene éxito. Entonces puedes registrar tus errores y éxitos con marcas de tiempo. El registro ahora le permite saber todo lo que su script ha hecho, el éxito o el fracaso.
PowerShell no es su única opción
Mientras que PowerShell es una herramienta útil para un montón de tareas de Windows, puede ser difícil de aprender. También no es adecuado para todo. Si usted está haciendo el mantenimiento del sistema en su ordenador o la comprobación de la integridad de un archivo, PowerShell es útil. En cambio, si lo que quieres es ejecutar un script para descargar archivos de Internet o alguna tarea más general, tienes otras opciones.
Por ejemplo, si vienes de un entorno Unix o Linux, puede que te sientas más cómodo utilizando el shell bash. Gracias al subsistema de Windows para Linux, ahora puedes utilizar fácilmente bash y otras herramientas de Linux en tu ordenador con Windows 10. Si eso te parece perfecto, no busques más que nuestra guía para hacer funcionar el shell bash en Windows 10.
Kris Wouk es músico, escritor y lo que sea que se llame cuando alguien hace videos para la web. Entusiasta de la tecnología desde que tiene uso de razón, sin duda tiene sistemas operativos y dispositivos favoritos, pero utiliza todos los que puede de todos modos, sólo para estar al día.
Más de Kris Wouk