Compartilhar via


Adicionar relatórios de erros de não encerramento ao seu cmdlet

Os cmdlets podem relatar erros não roteados chamando o método System.Management.Automation.Cmdlet.WriteError e ainda continuar a operar no objeto de entrada atual ou em outros objetos de pipeline de entrada. Esta seção explica como criar um cmdlet que relata erros não finalização de seus métodos de processamento de entrada.

Para erros não finalização (bem como erros de encerramento), o cmdlet deve passar um objeto System.Management.Automation.ErrorRecord identificando o erro. Cada registro de erro é identificado por uma cadeia de caracteres exclusiva chamada "identificador de erro". Além do identificador, a categoria de cada erro é especificada por constantes definidas por uma enumeração System.Management.Automation.ErrorCategory. O usuário pode exibir erros com base em sua categoria definindo a $ErrorView variável como "CategoryView".

Para obter mais informações sobre registros de erro, consulte Windows PowerShell erros.

Definindo o cmdlet

A primeira etapa na criação do cmdlet é sempre nomear o cmdlet e declarar a classe .NET que implementa o cmdlet. Esse cmdlet recupera informações do processo, portanto, o nome do verbo escolhido aqui é "Get". (Quase qualquer tipo de cmdlet capaz de recuperar informações pode processar a entrada de linha de comando.) Para obter mais informações sobre verbos de cmdlet aprovados, consulte Nomes de verbos do cmdlet.

A seguir está a definição desse Get-Proc cmdlet. Os detalhes dessa definição são dados em Criando seu primeiro cmdlet.

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

Definindo parâmetros

Se necessário, o cmdlet deve definir parâmetros para processar a entrada. Este Get-Proc cmdlet define um parâmetro Name conforme descrito em Adicionando parâmetros que processam Command-Line entrada.

Aqui está a declaração de parâmetro para o parâmetro Name deste Get-Proc cmdlet.

[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

Substituindo métodos de processamento de entrada

Todos os cmdlets devem substituir pelo menos um dos métodos de processamento de entrada fornecidos pela classe System.Management.Automation.Cmdlet. Esses métodos são discutidos em Criando seu primeiro cmdlet.

Observação

O cmdlet deve manipular cada registro da maneira mais independente possível.

Esse Get-Proc cmdlet substitui o método System.Management.Automation.Cmdlet.ProcessRecord para manipular o parâmetro Name para entrada fornecida pelo usuário ou um script. Esse método obterá os processos para cada nome de processo solicitado ou todos os processos se nenhum nome for fornecido. Os detalhes dessa substituição são dados em Criando seu primeiro cmdlet.

Coisas a lembrar ao relatar erros

O objeto System.Management.Automation.ErrorRecord que o cmdlet passa ao escrever um erro requer uma exceção em seu núcleo. Siga as diretrizes do .NET ao determinar a exceção a ser usada. Basicamente, se o erro for semanticamente o mesmo que uma exceção existente, o cmdlet deverá usar ou derivar dessa exceção. Caso contrário, ele deverá derivar uma nova hierarquia de exceção ou exceção diretamente da classe System.Exception.

Ao criar identificadores de erro (acessados por meio da propriedade FullyQualifiedErrorId da classe ErrorRecord), lembre-se do seguinte.

  • Use cadeias de caracteres direcionadas para fins de diagnóstico para que, ao inspecionar o identificador totalmente qualificado, você possa determinar qual é o erro e de onde o erro veio.

  • Um identificador de erro totalmente qualificado bem formado pode ser o seguinte.

    CommandNotFoundException,Microsoft.PowerShell.Commands.GetCommandCommand

Observe que, no exemplo anterior, o identificador de erro (o primeiro token) designa qual é o erro e a parte restante indica de onde o erro veio.

  • Para cenários mais complexos, o identificador de erro pode ser um token separado por ponto que pode ser analisado na inspeção. Isso permite ramificar também as partes do identificador de erro, bem como o identificador de erro e a categoria de erro.

O cmdlet deve atribuir identificadores de erro específicos a caminhos de código diferentes. Lembre-se das seguintes informações para atribuição de identificadores de erro:

  • Um identificador de erro deve permanecer constante durante todo o ciclo de vida do cmdlet. Não altere a semântica de um identificador de erro entre as versões do cmdlet.
  • Use texto para um identificador de erro que corresponde tersely ao erro que está sendo relatado. Não use espaço em branco ou pontuação.
  • Fazer com que seu cmdlet gere apenas identificadores de erro que sejam reproduzíveis. Por exemplo, ele não deve gerar um identificador que inclua um identificador de processo. Identificadores de erro são úteis para um usuário somente quando correspondem a identificadores vistos por outros usuários que enfrentam o mesmo problema.

Exceções sem manuseio não são capturadas pelo PowerShell nas seguintes condições:

  • Se um cmdlet criar um novo thread e o código em execução nesse thread gerar uma exceção sem tratamento, o PowerShell não capturará o erro e encerrará o processo.
  • Se um objeto tiver código em seu destruidor ou métodos Dispose que causem uma exceção sem tratamento, o PowerShell não capturará o erro e encerrará o processo.

Relatando erros não roteando

Qualquer um dos métodos de processamento de entrada pode relatar um erro não finalização para o fluxo de saída usando o método System.Management.Automation.Cmdlet.WriteError.

Aqui está um exemplo de código deste cmdlet Get-Proc que ilustra a chamada para System.Management.Automation.Cmdlet.WriteError de dentro da substituição do método System.Management.Automation.Cmdlet.ProcessRecord. Nesse caso, a chamada será feita se o cmdlet não puder encontrar um processo para um identificador de processo 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
  }

Coisas a se lembrar sobre como escrever erros não roteando

Para um erro não final, o cmdlet deve gerar um identificador de erro específico para cada objeto de entrada específico.

Um cmdlet frequentemente precisa modificar a ação do PowerShell produzida por um erro não final. Ele pode fazer isso definindo os ErrorAction ErrorVariable parâmetros e . Se definir o parâmetro , o cmdlet apresentará as opções de usuário ErrorAction System.Management.Automation.ActionPreference, você também poderá influenciar diretamente a ação definindo a $ErrorActionPreference variável.

O cmdlet pode salvar erros não finalização em uma variável usando o parâmetro , que não é ErrorVariable afetado pela configuração de ErrorAction . As falhas podem ser acrescentadas a uma variável de erro existente adicionando um sinal de adição (+) à frente do nome da variável.

Exemplo de código

Para obter o código de exemplo C# completo, consulte GetProcessSample04 Sample.

Definir tipos de objeto e formatação

O PowerShell passa informações entre cmdlets usando objetos .NET. Consequentemente, um cmdlet pode precisar definir seu próprio tipo ou o cmdlet pode precisar estender um tipo existente fornecido por outro cmdlet. Para obter mais informações sobre como definir novos tipos ou estender tipos existentes, consulte Estendendo tipos de objeto e formatação.

Criando o cmdlet

Depois de implementar um cmdlet, você deve registrá-lo com Windows PowerShell por meio de Windows PowerShell snap-in. Para obter mais informações sobre como registrar cmdlets, consulte How to Register Cmdlets, Providers, and Host Applications.

Testando o cmdlet

Quando o cmdlet tiver sido registrado com o PowerShell, você poderá testá-lo executando-o na linha de comando. Vamos testar o cmdlet Get-Proc exemplo para ver se ele relata um erro:

  • Inicie o PowerShell e use o cmdlet Get-Proc para recuperar os processos chamados "TEST".

    get-proc -name test
    

    A saída a seguir aparece.

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

Consulte Também

Adicionar parâmetros que processam a entrada de pipeline

Adicionando parâmetros que processam Command-Line entrada

Criando seu primeiro cmdlet

Estendendo tipos de objeto e formatação

Como registrar cmdlets, provedores e aplicativos de host

Referência do Windows PowerShell

Amostras de cmdlet