Agregar informes de errores sin terminación a su cmdlet
Los cmdlets pueden informar errores que no terminan 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. Esta sección explica cómo crear un cmdlet que informe errores de no terminación de sus métodos de procesamiento de entrada.
Para errores que no terminan (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 según su categoría configurando la variable $ErrorView en "CategoryView".
Para obtener más información sobre los registros de errores, consulte Registros de errores de Windows PowerShell.
Definición del cmdlet
El primer paso en la creación de un cmdlet es siempre nombrar el cmdlet y declarar la clase .NET que implementa el cmdlet. Este cmdlet recupera información del proceso, por lo que el nombre del verbo elegido aquí es "Obtener". (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.
La siguiente es 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, su cmdlet debe definir parámetros para procesar la entrada. Este cmdlet Get-Proc define un parámetro Name como se describe en Agregar parámetros que procesan la entrada de la línea de comandos.
Aquí está 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
Anulació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 analizan en Creación del primer cmdlet.
Nota
Su cmdlet debe manejar cada registro de la manera más independiente posible.
Este cmdlet Get-Proc anula 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 para cada nombre de proceso solicitado o todos los procesos si no se proporciona ningún nombre. Los detalles de esta anulación se proporcionan en Creación del primer cmdlet.
Cosas para recordar al informar errores
El objeto System.Management.Automation.ErrorRecord que pasa el cmdlet al escribir un error requiere una excepción en su núcleo. Siga las pautas de .NET al determinar la excepción a utilizar. 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, debería derivar una nueva excepción o jerarquía de 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.
Utilice 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 proviene.
Un identificador de error completo y 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 vino el error.
- Para escenarios más complejos, el identificador de error puede ser un token separado por puntos que se puede analizar durante la inspección. Esto también le permite 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 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 versiones de cmdlet.
- Utilice texto para un identificador de error que corresponda brevemente al error que se informa. No utilice espacios en blanco ni puntuación.
- Haga que su cmdlet genere solo identificadores de error que sean reproducibles. Por ejemplo, no debería 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 las excepciones no controladas en las siguientes condiciones:
- Si un cmdlet crea un nuevo subproceso y el código que se ejecuta en ese subproceso genera 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.
Informar errores no terminantes
Cualquiera de los métodos de procesamiento de entrada puede informar un error de no terminación al flujo de salida mediante el método System.Management.Automation.Cmdlet.WriteError.
A continuación se muestra un ejemplo de código de este cmdlet Get-Proc que ilustra la llamada a System.Management.Automation.Cmdlet.WriteError desde la anulación del método System.Management.Automation.Cmdlet.ProcessRecord. En este caso, la llamada se realiza si el cmdlet no puede encontrar un proceso para un identificador de proceso específico.
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 para recordar acerca de la escritura de errores no terminantes
Para un error que no termina, el cmdlet debe generar un identificador de error específico para cada objeto de entrada específico.
Con frecuencia, un cmdlet necesita modificar la acción de PowerShell producida por un error de no terminación. Puede hacer esto 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 configurando la variable $ErrorActionPreference.
El cmdlet puede guardar errores que no terminan en una variable mediante el parámetro ErrorVariable, que no se ve afectado por la configuración de ErrorAction. Las fallas se pueden agregar 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 muestra completo de C#, consulte Ejemplo GetProcessSample04.
Definir tipos de objetos y formato
PowerShell pasa información entre cmdlets mediante objetos .NET. En consecuencia, es posible que un cmdlet deba definir su propio tipo o que el cmdlet deba ampliar un tipo existente proporcionado por otro cmdlet. Para obtener más información sobre cómo definir nuevos tipos o ampliar tipos existentes, consulte Ampliación de tipos de objetos y formato.
Construyendo el cmdlet
Después de implementar un cmdlet, debe registrarlo en Windows PowerShell a través de un complemento de Windows PowerShell. Para obtener más información sobre el registro de cmdlets, consulte Cómo registrar cmdlets, proveedores y aplicaciones host.
Probando el cmdlet
Cuando su cmdlet se haya registrado en PowerShell, puede probarlo ejecutándolo en la línea de comandos. Probemos el cmdlet Get-Proc de muestra para ver si informa un error:
Inicie PowerShell y use el cmdlet Get-Proc para recuperar los procesos denominados "TEST".
get-proc -name testAparece 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
Ver también
Agregar parámetros que procesan la entrada de canalización
Agregar parámetros que procesan la entrada de la línea de comandos
Creando su primer cmdlet
Ampliación de tipos de objetos y formato
Cómo registrar cmdlets, proveedores y aplicaciones host
Referencia de Windows PowerShell
Ejemplos de cmdlets