Una de las partes clave de cualquier script de PowerShell bueno es el manejo de errores. Incluso en el script más corto, ser capaz de manejar errores ayuda a garantizar que un evento inesperado no destruya el sistema en el que está trabajando. Tome el ejemplo a continuación. Cada semana en nuestra empresa de muestra (MyCompany.Com Recursos Humanos va a subir una lista que nos dice quién debe tener acceso a la base de datos de gastos., Si un nombre no está en la lista de recursos humanos vamos a eliminarlo del grupo y ese usuario ya no podrá registrar las reclamaciones de gastos:
ahora, puede ver dónde va a salir mal. Una semana HR no se acerca a subir la lista o, justo cuando estamos a punto de acceder a la lista, el servidor de archivos muere. De repente, PowerShell genera un error en el cmdlet Get-Content y la variable Author AuthorizedUser permanece vacía. Debido a que nuestro script no maneja errores, continúa ejecutándose y, en un espacio de tiempo muy corto, ha eliminado a todos los usuarios de nuestro grupo de gastos., Muy pronto las furiosas llamadas telefónicas comienzan a inundarse y la vida se vuelve un poco menos feliz. La forma de evitar todo esto es atrapar los errores y luego manejar el evento que los causó (que en este caso es detener el script y gritar a alguien en Recursos Humanos).
Errores de terminación y no terminación
Una de las cosas clave que debe saber al detectar errores es que solo ciertos errores se pueden detectar de forma predeterminada. Los errores vienen en dos tipos: terminantes y no terminantes. Un error de terminación es un error que detendrá una función u operación., Si comete un error de sintaxis o se queda sin memoria, se trata de un error de terminación. Los errores de terminación se pueden detectar y manejar. Los errores que no terminan permiten que Powershell continúe y, por lo general, provienen de cmdlets u otras situaciones administradas. En circunstancias normales no pueden ser capturados por Try-Catch-Finally. El error Get-Content del ejemplo anterior es un error que no termina.
tratar los errores no terminantes como terminantes
entonces, ¿cómo se detecta un error No terminante? Básicamente, le dices a PowerShell que lo trate como una terminación. Para ello se utiliza el parámetro ErrorAction., Cada cmdlet de PowerShell admite ErrorAction. Al especificar-ErrorAction Stop al final de un cmdlet, se asegura de que cualquier error que arroje se trate como terminación y se pueda detectar. En nuestro ejemplo anterior vamos a cambiar nuestra línea Get-Content a:
$AuthorizedUsers= Get-Content \\ FileServer\HRShare\UserList.txt -ErrorAction Stop
tratar todos los errores como terminantes
también es posible tratar todos los errores como terminantes usando la variable ErrorActionPreference. Puede hacerlo para el script con el que está trabajando o para toda la sesión de PowerShell. Para configurarlo en un script, haga la primera línea er ErrorActionPreference = Stop., Para configurarlo para la sesión, escriba $ErrorActionPreference = Stop en la consola de PowerShell.
captando un Error de terminación
Una vez que se haya asegurado de que el error que está tratando de capturar se tratará como terminación, puede construir un bloque Try Catch alrededor del comando (o comandos) que podrían causar el error. La primera etapa es rodear la sección de su script que puede lanzar el error con un bloque de prueba. En nuestro ejemplo, la línea Get-Content se convierte en:
Try{ $AuthorizedUsers= Get-Content \\ FileServer\HRShare\UserList.txt -ErrorAction Stop}
inmediatamente después del bloque Try debe colocar un bloque Catch para tratar el error., Solo se accede al bloque Catch si se produce un error de finalización; de lo contrario, se ignora. En nuestro ejemplo vamos a enviar un correo electrónico a un administrador para decir que ha habido un error y luego detener el script. Nuestra línea Get-Content es ahora:
acceder al registro de Error
Una vez que esté dentro de un bloque catch, puede acceder al registro de error, que se almacena en la variable de objeto actual,$_. Los registros de errores tienen varias propiedades útiles, pero la principal a la que querrá acceder es $_.Salvedad., Las excepciones son lo que realmente estamos tratando aquí a medida que detectamos y tratamos con los errores: las excepciones son el evento inesperado que causó el error (el registro de error en sí es en realidad solo un contenedor para presentar la excepción al usuario de PowerShell). Es la excepción que estamos atrapando y la excepción que contiene toda la información realmente útil sobre el problema. Si hubo otro problema subyacente que causó nuestra excepción, también se registra en $_.salvedad.innerexception (y así sucesivamente – la siguiente excepción subyacente se almacena en $_.salvedad.innerexception.,innerexception etc.). Para los propósitos de nuestro ejemplo vamos a usar $_.Excepción para poner algo de información adicional en nuestro correo electrónico de notificación, utilizando el $_.Salvedad.Mensaje y $_.Salvedad.Propiedades del nombre del artículo:
captura de excepciones específicas
ahora, como está nuestro ejemplo, estamos detectando cualquier error que ocurra durante la lectura del archivo y tratándolos todos de la misma manera. Sin embargo, puede detectar excepciones específicas y tratarlas de manera diferente, pero – y es un gran pero – solo si el error original está terminando., Porque el cmdlet Get-Content tiros no los errores de terminación (que sólo hemos tratado como terminación utilizando ErrorAction) no podemos detectar específicamente las diferentes excepciones que el cmdlet podría lanzar. Esta es una característica de PowerShell y se aplica a cualquier error de terminación, independientemente de la ErrorActionPreference y no se puede cambiar. Aún así, podemos lidiar con otras excepciones de terminación, como un error de memoria, que podría aparecer durante la operación de lectura. Para los propósitos de este ejemplo eso es lo que haremos.,
Puede detectar errores de terminación específicos especificando el nombre de la excepción inmediatamente después de la palabra clave Catch. En nuestro ejemplo queremos atrapar un sistema.OutOfMemory exception y, si obtenemos una, tomará el enfoque sin sentido de reiniciar el equipo inmediatamente. También incluiremos un bloque catch general después de nuestro bloque file not found para capturar todas las demás excepciones:
finalmente, usando Finally
La última parte de Try Catch Finally es el bloque Finally. Esto se debe definir inmediatamente después del bloque Catch y se ejecuta cada vez, independientemente de si hubo un error o no., De esta manera, puede realizar acciones que deben realizarse independientemente de si una operación tiene éxito o falla. En nuestro ejemplo vamos a registrar que se intentó leer un archivo. Nuestra línea Get-Content ahora se ve así: