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

Los cmdlets pueden notificar errores no terminales llamando al método System.Management.Automation.Cmdlet.WriteError y seguir 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 notifica errores no terminales de sus métodos de procesamiento de entrada.

Para errores no terminales (así como errores de terminación), el cmdlet debe pasar un objeto System.Management.Automation.ErrorRecord que identifique 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 $ErrorView variable en "CategoryView".

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

Definición del cmdlet

El primer paso en la creación de cmdlets es asignar siempre 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, vea Nombres de verbos de cmdlet.

A continuación se muestra la definición de este Get-Proc cmdlet. Los detalles de esta definición se detallan 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 Get-Proc cmdlet define un parámetro Name como se describe en Adding Parameters that Process Command-Line Input (Agregar parámetros que procesan Command-Line entrada).

Esta es la declaración de parámetro para el parámetro Name de este cmdlet 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

Invalidar 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 de abordan en Creación del primer cmdlet.

Nota

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

Este cmdlet 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 obtiene 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 detallan en Creación del primer cmdlet.

Cosas que debe 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 usará. Básicamente, si el error es semánticamente el mismo 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 de la clase System.Exception.

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 cuál es el error y de dónde salió 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 cuál es el error y la parte restante indica de dónde salió el error.

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

El cmdlet debe asignar identificadores de error específicos a distintas 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 a lo largo del 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.
  • Hacer que el cmdlet genere solo identificadores de error que se puedan 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 que otros usuarios ven que experimentan el mismo problema.

PowerShell no detecta excepciones no controladas en las condiciones siguientes:

  • Si un cmdlet crea un nuevo subproceso y el 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 produce una excepción no controlada, PowerShell no detectará el error y finalizará el proceso.

Notificar errores no terminales

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

Este es un ejemplo de código de este cmdlet Get-Proc que muestra 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 nonterminating 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 debe recordar sobre la escritura de errores no terminales

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

Con frecuencia, un cmdlet debe modificar la acción de PowerShell producida por un error no terminal. Para ello, puede definir los ErrorAction parámetros ErrorVariable y . Si define el parámetro , el cmdlet presenta las opciones de usuario ErrorAction System.Management.Automation.ActionPreference, también puede influir directamente en la acción estableciendo la $ErrorActionPreference variable .

El cmdlet puede guardar errores no terminales en una variable mediante el parámetro , que ErrorVariable 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 frente del nombre de la variable.

Ejemplo de código

Para obtener el código de ejemplo completo de C#, vea GetProcessSample04 Sample.

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 ampliar un tipo existente proporcionado por otro cmdlet. Para obtener más información sobre cómo definir nuevos tipos o ampliar los tipos existentes, vea Extender tipos de objetos y Aplicar formatoa .

Compilar el cmdlet

Después de implementar un cmdlet, debe registrarlo con Windows PowerShell un Windows PowerShell complemento. Para obtener más información sobre cómo registrar cmdlets, vea How to Register Cmdlets, Providers, and Host Applications.

Prueba del cmdlet

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

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

    get-proc -name test
    

    Aparece el siguiente resultado.

    get-proc : Operation is not valid due to the current state of the object.
    At line:1 char:9
    + get-proc  <<<< -name test
    

Consulte también

Adición de parámetros que procesan la entrada de la canalización

Adición de parámetros que procesan Command-Line entrada

Creación del primer cmdlet

Extensión de tipos de objeto y formato

Cómo registrar cmdlets, proveedores y aplicaciones host

Referencia de Windows PowerShell

Ejemplos de cmdlet