Windows PowerShellCaptura de errores

Don Jones

Contenido

Configuración de una captura
Detener.
Está todo en el ámbito
Romper fuera
¿Por qué preocuparse?

Vídeo

Continuar su explicación sobre la creación de una herramienta eficaz inventorying en Windows PowerShell, Don Jones activa su atención a intercepción de errores.En de vídeo que lo acompaña este mes, Don muestra cómo puede incorporar tratamiento de errores en sus funciones en función de Windows PowerShell.

En la entrega anterior de esta columna, mostré cómo hacer que una herramienta de inventario en su lugar avanzada uso de Windows PowerShell.La herramienta se ha creado ofrece varias opciones acerca de salida, gracias a funciones integradas del shell y uso de la función de objetos.

Un aspecto hay que reconocer que débil de la función que se ha creado es que no se puede tratar correctamente los errores que pueden producirse, como problemas de conectividad o de permisos.Que es lo que va a dirección de entrega de este mes de la columna de Windows PowerShell, estoy viendo las capacidades de tratamiento de errores que ofrece Windows PowerShell.

Configuración de una captura

La palabra clave de captura en Windows PowerShell define un controlador de errores.Cuando se produce una excepción en la secuencia de comandos, el shell parece para ver si se ha definido un reventado, esto significa la captura debe aparecer en la secuencia de comandos antes de que ocurran las excepciones.Para esta demostración, le reunir una secuencia de prueba que se sabe generará un problema de conectividad: VOY a utilizar Get-WmiObject para conectarse a un nombre de equipo que sé que no existe en la red.Mi objetivo es que la captura de error escriben el nombre de equipo incorrecto en un archivo, me da un archivo de nombres de equipo que no funcionan.También le incluya conexiones a dos equipos que son accesibles (VOY a utilizar localhost).Puede ver la secuencia de comandos en la figura 1 .

Figura 1, agregar la captura

trap {
  write-host "Error connecting to $computer" -fore red
  "$computer" | out-file c:\demo\errors.txt -append 
  continue
}

$computer = "localhost"
get-wmiobject win32_operatingsystem -comp $computer 

$computer = "server2"
get-wmiobject win32_operatingsystem -comp $computer 

$computer = "localhost"
get-wmiobject win32_operatingsystem -comp $computer

El resultado de esta secuencia de comandos, que se muestra en la figura 2 , es no es exactamente lo que ESTOY buscando. Observe que no muestran el mensaje "Error de conexión to…". El archivo Errors.txt no se creó una. En otras palabras, la captura no ejecuta en absoluto. ¿Qué ha ocurrido?

fig02.gif

La Figura 2 esto no es el resultado se esperando para!

Detener.

La clave es entender que un mensaje de error shell normal no es igual una excepción. (Hay errores sin terminar y errores de terminación. Errores de terminación detiene la ejecución de la canalización y el resultado en una excepción.) Se pueden capturar excepciones sólo. Cuando se produce un error, el shell examina su variable de ErrorActionPreference $ integrada para ver lo que debe hacer. Valor predeterminado de dicha variable es tener el valor "Continuar", lo que significa "mostrar un mensaje de error y mantener va". Cambiar esta variable a "detener" haría que él para mostrar un mensaje de error y producir una excepción capturable. Sin embargo, esto significa que cualquier error en la secuencia de comandos hará lo.

Una técnica mejor es que sólo el cmdlet que piensa podría provocar un uso problema el comportamiento de "detener". Para ello puede mediante el parámetro –ErrorAction (o –EA), un parámetro comunes compatible con todos los cmdlets. La versión revisada de la secuencia de comandos se muestra en la figura 3 . Funciona sólo como se esperaba, producir el resultado que encontrará en la figura 4 .

Uso de la figura 3 - ErrorAction

trap {
  write-host "Error connecting to $computer" -fore red
    "$computer" | out-file c:\demo\errors.txt -append 
  continue
}

$computer = "localhost"
get-wmiobject win32_operatingsystem -comp $computer -ea stop

$computer = "server2"
get-wmiobject win32_operatingsystem  -comp $computer -ea stop

$computer = "localhost"
get-wmiobject win32_operatingsystem  -comp $computer -ea stop

La figura 4 obtener resultados más útiles cuando se utiliza el parámetro –ErrorAction

El uso de continuar al final de la captura indica el shell para reanudar la ejecución en la línea de código después de la que produjo la excepción. La otra opción es utilizar la palabra clave BREAK (trataré que en un momento). Observe también que la variable $ del equipo, que se define en la secuencia de comandos, es siendo válida dentro de la captura. Porque la captura es un ámbito de secundario de la propia secuencia de comandos, lo que significa que la captura puede ver todas las variables en la secuencia de comandos (más información sobre esto en un momento, también).

Está todo en el ámbito

Un aspecto especialmente difícil de captura de errores de Windows PowerShell es el uso del ámbito. El shell propio representa el ámbito global, que contiene todo lo que pasa en el shell. Cuando se ejecuta una secuencia de comandos, obtiene su propio ámbito de secuencia de comandos. Si define una función, dentro de la función es su propio ámbito privada y así sucesivamente. Esto crea un tipo de tipo de matriz/filial de la jerarquía.

Cuando se produce una excepción, el shell busca un reventado en el ámbito actual. Esto significa que una excepción dentro de una función buscará un reventado dentro de esa función. Si el shell encuentra un reventado, el shell ejecuta la captura. Si la captura finaliza con continuar, el shell reanudará la ejecución en la línea de código que sigue a la que provocó la excepción, en el mismo ámbito. Éste es un poco de seudocódigo para ayudar a ilustrar esto:

01  Trap {
02    # Log error to a file
03    Continue
04  }
05  Get-WmiObject Win32_Service –comp "Server2" –ea "Stop"
06  Get-Process

Si se produce una excepción en línea 5, se ejecutará el reventado de línea de 1. La captura finaliza con continuar, por lo que se reanudará la ejecución en línea 6.

Ahora Considere este ejemplo ligeramente diferente de ámbito:

01  Trap {
02    # Log error to a file
03    Continue
04  }
05   
06  Function MyFunction {
07    Get-WmiObject Win32_Service –comp "Server2" –ea "Stop"
08    Get-Process
09  }
10   
11  MyFunction
12  Write-Host "Testing!"

Si se produce un error en línea 7, el shell buscará un reventado en ámbito de la función. No hay uno, por lo que el shell sale de ámbito de la función y busca un reventado en el ámbito principal. No hay un reventado y por lo que ejecuta en la línea 1. En este caso, continuar se reanudará en la línea de código en el mismo ámbito que seguido de la excepción, que es 12 de línea, no línea 8. En otras palabras, el shell no a escribir la función de una vez que se sale.

Ahora, compare ese comportamiento con este ejemplo:

01  Function MyFunction {
02    Trap {
03      # Log error to a file
04      Continue
05    }
06    Get-WmiObject Win32_Service –comp "Server2" –ea "Stop"
07    Get-Process
08  }
09   
10  MyFunction
11  Write-Host "Testing!"

En este caso, el error en línea 6 ejecutará el reventado de línea 2, desvía el ámbito de la función. La palabra clave continuar permanecerá dentro de ese ámbito, reanudar la ejecución en línea 7. Se trata de la ventaja a incluir un reventado en el ámbito donde espera que el error producido, permanecen dentro de ámbito y pueden reanudar la ejecución en él. Pero ¿qué sucede si este método no funciona en el escenario?

Cmdlet del mes: objeto de comparar

Esto es una herramienta interesante para administrar líneas de base de configuración. Objeto de comparar, o su alias Diff, está diseñado para comparar dos conjuntos de objetos a uno del otro. De forma predeterminada, compara cada propiedad de cada objeto y las diferencias son resultados con el comando. Por lo que suponga que ha llegado un servidor de servicios configurados exactamente la forma que desee. Simplemente ejecute esta opción para crear una línea de base:

Get-Service | Export-CliXML c:\baseline.xml

Casi cualquier objeto se puede canalizar a CliXML exportar, que pasará a los objetos en un archivo XML. Posteriormente, puede ejecutar el mismo comando, como Get-Service y comparar los resultados a la que guardan XML. He aquí cómo:

Compare-Object (Get-Service) (Import-CliXML 
  c:\baseline.xml) –property name

Agregar el parámetro –property obliga a la comparación para ver sólo esa propiedad, en lugar de todo el objeto. En este caso, obtendrá una lista de los nombres de servicio que sean diferentes de la línea de base original, permitiéndole sabe si los servicios tiene ha agregado o eliminado desde que se creó la línea de base.

Romper fuera

Anteriormente, he mencionado la palabra clave BREAK. la figura 5 muestra un ejemplo de cómo puede poner la palabra clave BREAK en acción.

La figura 5 mediante la palabra clave BREAK

01  Trap {
02    # Handle the error
03    Continue
04  }
05   
06  Function MyFunction {
07    Trap {
08      # Log error to a file
09      If ($condition) {
10        Continue
11      } Else {
12        Break
13      }
14    }
15    Get-WmiObject Win32_Service –comp "Server2" –ea "Stop"
16    Get-Process
17  }
18   
19  MyFunction
20  Write-Host "Testing!"

Esto es una introducción rápida de la cadena de ejecución. Línea 19 ejecuta primero, llamar a la función en línea 6. Línea 15 ejecuta y genera una excepción. Esa excepción se captura en línea 7 y, a continuación, en línea 9 la captura debe realice una decisión. Suponiendo que $ condición es True, la captura continuará ejecución en línea 16.

Si, sin embargo, $ condición es false, se interrumpir la captura. Esto sale del ámbito actual y pasa la excepción original hacia arriba al principal. Desde vista el shell, que significa que la línea 19 genera una excepción, que se capturan con línea 1. La palabra clave continuar fuerza el shell para reanudar en línea 20.

En realidad, ambos de estos capturas tendría un poco más código en ellos para tratar el error, iniciar y así sucesivamente. HE omitido simplemente ese código funcional en este ejemplo para que el flujo real sea más fácil ver.

¿Por qué preocuparse?

Cuándo ¿necesita implementar la captura de errores? Sólo cuando se anticipó que es posible que se producirá un error, y cuándo desea algún comportamiento other than un mensaje de error sin formato, como registrar el error en un archivo o mostrar un mensaje de error más útil.

Normalmente, incluyen control de errores de secuencias de comandos más complicadas para ayudar a tratar errores que puede imaginar ocurra. Estos incluyen, pero no se limitan a, errores, como problemas de conectividad o permisos incorrectos.

Captura de errores definitivamente requiere un poco más esfuerzo y tiempo entender. Sin como progreso en tareas más complicadas en Windows PowerShell, embargo, captura de errores será también merece la pena la inversión para ayudar a que una herramienta más pulida y profesional.

Don Jones es el coautor de Windows PowerShell: TFM y autor de docenas de otros libros de INFORMÁTICA. Puede ponerse a través de su blog en concentratedtech.com.