Compartir a través de


Adición de informes de errores de no terminación al cmdlet

Los cmdlets pueden notificar errores de no terminación llamando al método System.Management.Automation.Cmdlet.WriteError y siguen funcionando en el objeto de entrada actual o en otros objetos de canalización entrantes. En esta sección se explica cómo crear un cmdlet que notifique errores de no terminación a partir de sus métodos de procesamiento de entrada.

Para errores de no terminación (así como errores de terminación), el cmdlet debe pasar un objeto System.Management.Automation.ErrorRecord que identifica el error. Cada registro de error se identifica mediante una cadena única denominada "identificador de error". Además del identificador, la categoría de cada error se especifica mediante constantes definidas por una enumeración System.Management.Automation.ErrorCategory. El usuario puede ver los errores en función de su categoría estableciendo la variable $ErrorView en "CategoryView".

Para obtener más información sobre los registros de errores, vea registros de errores de Windows PowerShell.

Definición del cmdlet

El primer paso en la creación de cmdlets siempre es asignar un nombre al cmdlet y declarar la clase .NET que implementa el cmdlet. Este cmdlet recupera la información del proceso, por lo que el nombre del verbo elegido aquí es "Get". (Casi cualquier tipo de cmdlet que sea capaz de recuperar información puede procesar la entrada de la línea de comandos). Para obtener más información sobre los verbos de cmdlet aprobados, consulte Nombres de verbos de cmdlet.

A continuación se muestra la definición de este cmdlet Get-Proc. Los detalles de esta definición se proporcionan en Creación del primer cmdlet.

[Cmdlet(VerbsCommon.Get, "proc")]
public class GetProcCommand: Cmdlet
<Cmdlet(VerbsCommon.Get, "Proc")> _
Public Class GetProcCommand
    Inherits Cmdlet

Definición de parámetros

Si es necesario, el cmdlet debe definir parámetros para procesar la entrada. Este cmdlet de Get-Proc define un parámetro Name tal como se describe en Agregar parámetros que procesan Command-Line entrada.

Esta es la declaración de parámetros del parámetro Name de este cmdlet de Get-Proc.

[Parameter(
           Position = 0,
           ValueFromPipeline = true,
           ValueFromPipelineByPropertyName = true
)]
[ValidateNotNullOrEmpty]
public string[] Name
{
  get { return processNames; }
  set { processNames = value; }
}
private string[] processNames;
<Parameter(Position:=0, ValueFromPipeline:=True, _
ValueFromPipelineByPropertyName:=True), ValidateNotNullOrEmpty()> _
Public Property Name() As String()
    Get
        Return processNames
    End Get

    Set(ByVal value As String())
        processNames = value
    End Set

End Property

Invalidación de métodos de procesamiento de entrada

Todos los cmdlets deben invalidar al menos uno de los métodos de procesamiento de entrada proporcionados por la clase System.Management.Automation.Cmdlet. Estos métodos se describen en Creating Your First Cmdlet.

Nota:

El cmdlet debe controlar cada registro de la forma más independiente posible.

Este cmdlet de Get-Proc invalida el método System.Management.Automation.Cmdlet.ProcessRecord para controlar el parámetro Name para la entrada proporcionada por el usuario o un script. Este método obtendrá los procesos de cada nombre de proceso solicitado o de todos los procesos si no se proporciona ningún nombre. Los detalles de esta invalidación se proporcionan en Creación del primer cmdlet.

Cosas que recordar al notificar errores

El objeto System.Management.Automation.ErrorRecord que el cmdlet pasa al escribir un error requiere una excepción en su núcleo. Siga las instrucciones de .NET al determinar la excepción que se va a usar. Básicamente, si el error es semánticamente igual que una excepción existente, el cmdlet debe usar o derivar de esa excepción. De lo contrario, debe derivar una nueva jerarquía de excepciones o excepciones directamente desde la clase System.Exception de.

Al crear identificadores de error (a los que se accede a través de la propiedad FullyQualifiedErrorId de la clase ErrorRecord), tenga en cuenta lo siguiente.

  • Use cadenas destinadas a fines de diagnóstico para que, al inspeccionar el identificador completo, pueda determinar de qué es el error y de dónde procede el error.

  • Un identificador de error completo bien formado podría ser el siguiente.

    CommandNotFoundException,Microsoft.PowerShell.Commands.GetCommandCommand

Observe que en el ejemplo anterior, el identificador de error (el primer token) designa de qué es el error y la parte restante indica de dónde procede el error.

  • Para escenarios más complejos, el identificador de error puede ser un token separado por puntos que se puede analizar en la inspección. Esto le permite también bifurcarse en las partes del identificador de error, así como en el identificador de error y la categoría de error.

El cmdlet debe asignar identificadores de error específicos a diferentes rutas de acceso de código. Tenga en cuenta la siguiente información para la asignación de identificadores de error:

  • Un identificador de error debe permanecer constante durante todo el ciclo de vida del cmdlet. No cambie la semántica de un identificador de error entre las versiones del cmdlet.
  • Use texto para un identificador de error que se corresponda con el error que se notifica. No use espacios en blanco ni signos de puntuación.
  • Haga que el cmdlet genere solo identificadores de error que se pueden reproducir. Por ejemplo, no debe generar un identificador que incluya un identificador de proceso. Los identificadores de error son útiles para un usuario solo cuando corresponden a identificadores vistos por otros usuarios que experimentan el mismo problema.

PowerShell no detecta excepciones no controladas en las condiciones siguientes:

  • Si un cmdlet crea un nuevo subproceso y código que se ejecuta en ese subproceso produce una excepción no controlada, PowerShell no detectará el error y finalizará el proceso.
  • Si un objeto tiene código en su destructor o métodos Dispose que provocan una excepción no controlada, PowerShell no detectará el error y finalizará el proceso.

Notificación de errores de no terminación

Cualquiera de los métodos de procesamiento de entrada puede notificar un error de no terminación al flujo de salida mediante el método System.Management.Automation.Cmdlet.WriteError.

Este es un ejemplo de código de este cmdlet de Get-Proc que ilustra la llamada a System.Management.Automation.Cmdlet.WriteError desde la invalidación del método System.Management.Automation.Cmdlet.ProcessRecord. En este caso, la llamada se realiza si el cmdlet no encuentra un proceso para un identificador de proceso especificado.

protected override void ProcessRecord()
{
  // If no name parameter passed to cmdlet, get all processes.
  if (processNames == null)
  {
    WriteObject(Process.GetProcesses(), true);
  }
    else
    {
      // If a name parameter is passed to cmdlet, get and write
      // the associated processes.
      // Write a non-terminating error for failure to retrieve
      // a process.
      foreach (string name in processNames)
      {
        Process[] processes;

        try
        {
          processes = Process.GetProcessesByName(name);
        }
        catch (InvalidOperationException ex)
        {
          WriteError(new ErrorRecord(
                     ex,
                     "NameNotFound",
                     ErrorCategory.InvalidOperation,
                     name));
          continue;
        }

        WriteObject(processes, true);
      } // foreach (...
    } // else
  }

Cosas que recordar al escribir errores de no terminación

Para un error de no terminación, el cmdlet debe generar un identificador de error específico para cada objeto de entrada específico.

Un cmdlet suele tener que modificar la acción de PowerShell generada por un error que no finaliza. Puede hacerlo definiendo los parámetros ErrorAction y ErrorVariable. Si define el parámetro ErrorAction, el cmdlet presenta las opciones de usuario System.Management.Automation.ActionPreference, también puede influir directamente en la acción estableciendo la variable $ErrorActionPreference.

El cmdlet puede guardar errores de no terminación en una variable mediante el parámetro ErrorVariable, que no se ve afectado por la configuración de ErrorAction. Los errores se pueden anexar a una variable de error existente agregando un signo más (+) al principio del nombre de la variable.

Ejemplo de código

Para obtener el código de ejemplo de C# completo, consulte Ejemplo GetProcessSample04.

Definir tipos de objeto y formato

PowerShell pasa información entre cmdlets mediante objetos .NET. Por lo tanto, es posible que un cmdlet tenga que definir su propio tipo o que el cmdlet tenga que extender un tipo existente proporcionado por otro cmdlet. Para obtener más información sobre cómo definir nuevos tipos o ampliar tipos existentes, vea Extensión de tipos de objeto y formato.

Compilación del cmdlet

Después de implementar un cmdlet, debe registrarlo con Windows PowerShell a través de un complemento de Windows PowerShell. Para obtener más información sobre el registro de cmdlets, consulte Registro de cmdlets, proveedores y aplicaciones host.

Prueba del cmdlet

Cuando el cmdlet se haya registrado con PowerShell, puede probarlo ejecutándolo en la línea de comandos. Vamos a probar el cmdlet Get-Proc de ejemplo para ver si notifica un error:

  • Inicie PowerShell y use el cmdlet Get-Proc para recuperar los procesos denominados "TEST".

    Get-Proc -Name test
    

    Aparece la salida siguiente.

    Get-Proc : Operation is not valid due to the current state of the object.
    At line:1 char:9
    + Get-Proc  <<<< -Name test
    

Véase también