Dodawanie raportowania błędów niepowodujących zakończenia działania do polecenia cmdlet

Polecenia cmdlet mogą zgłaszać błędy nieokreślone, wywołując metodę System.Management.Automation.Cmdlet.WriteError i nadal działają na bieżącym obiekcie wejściowym lub na dalszych przychodzących obiektach potoku. W tej sekcji wyjaśniono, jak utworzyć polecenie cmdlet, które zgłasza błędy niepowiązywające się z metod przetwarzania danych wejściowych.

W przypadku błędów nieokreślonych (a także błędów zakończenia) polecenie cmdlet musi przekazać obiekt System.Management.Automation.ErrorRecord identyfikujący błąd. Każdy rekord błędu jest identyfikowany przez unikatowy ciąg o nazwie "identyfikator błędu". Oprócz identyfikatora kategoria każdego błędu jest określana przez stałe zdefiniowane przez wyliczenie System.Management.Automation.ErrorCategory. Użytkownik może wyświetlać błędy na podstawie swojej kategorii, ustawiając $ErrorView zmienną na "CategoryView".

Aby uzyskać więcej informacji na temat rekordów błędów, zobacz Windows PowerShell błędów.

Definiowanie polecenia cmdlet

Pierwszym krokiem podczas tworzenia polecenia cmdlet jest zawsze nazewnictwo polecenia cmdlet i deklarowanie klasy .NET, która implementuje polecenie cmdlet. To polecenie cmdlet pobiera informacje o procesie, więc wybrana tutaj nazwa czasownika to "Get". (Niemal każdy rodzaj polecenia cmdlet, które może uzyskać informacje, może przetwarzać dane wejściowe wiersza polecenia). Aby uzyskać więcej informacji na temat zatwierdzonych czasowników cmdlet, zobacz Nazwy czasowników polecenia cmdlet.

Poniżej przedstawiono definicję tego Get-Proc polecenia cmdlet. Szczegółowe informacje o tej definicji znajdują się w tece Creating Your First Cmdlet (Tworzenie pierwszego polecenia cmdlet).

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

Definiowanie parametrów

W razie potrzeby polecenie cmdlet musi definiować parametry do przetwarzania danych wejściowych. To Get-Proc cmdlet definiuje parametr Name zgodnie z opisem w tece Adding Parameters that Process Command-Line Input.

Oto deklaracja parametru dla parametru Name tego 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

Zastępowanie metod przetwarzania danych wejściowych

Wszystkie polecenia cmdlet muszą zastąpić co najmniej jedną z metod przetwarzania danych wejściowych dostarczonych przez klasę System.Management.Automation.Cmdlet. Te metody zostały omówione w artykule Creating Your First Cmdlet (Tworzenie pierwszego polecenia cmdlet).

Uwaga

Polecenie cmdlet powinno obsługiwać każdy rekord tak niezależnie, jak to możliwe.

To Get-Proc cmdlet zastępuje metodę System.Management.Automation.Cmdlet.ProcessRecord w celu obsługi parametru Name dla danych wejściowych dostarczonych przez użytkownika lub skrypt. Ta metoda pobierze procesy dla każdej żądanej nazwy procesu lub wszystkich procesów, jeśli nie podano nazwy. Szczegóły tego przesłonięcia podano w te tematze Creating Your First Cmdlet (Tworzenie pierwszego polecenia cmdlet).

Co należy zapamiętać podczas raportowania błędów

Obiekt System.Management.Automation.ErrorRecord, który polecenie cmdlet przekazuje podczas zapisywania błędu, wymaga wyjątku. Podczas określania wyjątku do użycia postępuj zgodnie z wytycznymi dotyczącymi środowiska .NET. Zasadniczo, jeśli błąd jest semantycznie taki sam jak istniejący wyjątek, polecenie cmdlet powinno używać tego wyjątku lub pochodzić z niego. W przeciwnym razie powinna pochodzić od nowej hierarchii wyjątków lub wyjątków bezpośrednio z klasy System.Exception.

Podczas tworzenia identyfikatorów błędów (dostępnych za pośrednictwem właściwości FullyQualifiedErrorId klasy ErrorRecord) należy pamiętać o następujących kwestiach.

  • Użyj ciągów, które są docelowe do celów diagnostycznych, aby podczas inspekcji w pełni kwalifikowanego identyfikatora można było określić, co to jest błąd i skąd pochodzi błąd.

  • W pełni kwalifikowany identyfikator błędu może być następujący.

    CommandNotFoundException,Microsoft.PowerShell.Commands.GetCommandCommand

Zwróć uwagę, że w poprzednim przykładzie identyfikator błędu (pierwszy token) określa, czym jest błąd, a pozostała część wskazuje, skąd pochodzi błąd.

  • W przypadku bardziej złożonych scenariuszy identyfikator błędu może być tokenem oddzielonym kropką, który można analizowanie podczas inspekcji. Dzięki temu można również rozgałęzieć części identyfikatora błędu, a także identyfikator błędu i kategorię błędów.

Polecenie cmdlet powinno przypisywać określone identyfikatory błędów do różnych ścieżek kodu. Należy pamiętać o następujących informacjach dotyczących przypisywania identyfikatorów błędów:

  • Identyfikator błędu powinien pozostać stały przez cały cykl życia polecenia cmdlet. Nie zmieniaj semantyki identyfikatora błędu między wersjami polecenia cmdlet.
  • Użyj tekstu jako identyfikatora błędu, który odpowiada zgłaszanemu błędowi. Nie używaj białych znaków ani znaków interpunkcji.
  • Polecenie cmdlet musi generować tylko te identyfikatory błędów, które są powtarzalne. Na przykład nie powinna generować identyfikatora, który zawiera identyfikator procesu. Identyfikatory błędów są przydatne tylko wtedy, gdy odpowiadają identyfikatorom widocznym dla innych użytkowników, u których występuje ten sam problem.

Nieobsługiwane wyjątki nie są przechwycone przez program PowerShell w następujących warunkach:

  • Jeśli polecenie cmdlet tworzy nowy wątek i kod uruchomiony w tym wątku zgłasza nieobsługiwany wyjątek, program PowerShell nie przechwyci błędu i zakończy proces.
  • Jeśli obiekt ma kod w destruktorze lub metodach Dispose, które powodują nieobsługiwany wyjątek, program PowerShell nie przechwyci błędu i zakończy proces.

Raportowanie błędów nieokreślonych

Każda z metod przetwarzania danych wejściowych może zgłosić nieokreślony błąd do strumienia wyjściowego przy użyciu metody System.Management.Automation.Cmdlet.WriteError.

Oto przykład kodu z tego polecenia cmdlet programu Get-Proc, który ilustruje wywołanie metody System.Management.Automation.Cmdlet.WriteError z zastąpienia metody System.Management.Automation.Cmdlet.ProcessRecord. W takim przypadku wywołanie jest wykonane, jeśli polecenie cmdlet nie może znaleźć procesu dla określonego identyfikatora procesu.

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
  }

Co należy pamiętać o pisaniu błędów nieokreślonych

W przypadku błędu nieokreślanego polecenie cmdlet musi wygenerować określony identyfikator błędu dla każdego określonego obiektu wejściowego.

Polecenie cmdlet często musi modyfikować akcję programu PowerShell, która jest wielokrotnie przez błąd nieokreślony. Można to zrobić, definiując ErrorAction parametry ErrorVariable i . W przypadku definiowania parametru polecenie cmdlet przedstawia opcje użytkownika ErrorAction System.Management.Automation.ActionPreference, można również bezpośrednio wpływać na akcję, ustawiając $ErrorActionPreference zmienną.

Polecenie cmdlet może zapisać błędy nieokreślone w zmiennej przy użyciu parametru , na który nie ma wpływu ErrorVariable ustawienie ErrorAction . Błędy można dołączyć do istniejącej zmiennej błędu, dodając znak plus (+) z przodu nazwy zmiennej.

Przykład kodu

Aby uzyskać kompletny przykładowy kod w języku C#, zobacz GetProcessSample04 Sample (Przykład GetProcessSample04).

Definiowanie typów obiektów i formatowania

Program PowerShell przekazuje informacje między poleceniami cmdlet przy użyciu obiektów .NET. W związku z tym polecenie cmdlet może wymagać zdefiniowania własnego typu lub może być konieczne rozszerzenie istniejącego typu udostępnianego przez inne polecenie cmdlet. Aby uzyskać więcej informacji na temat definiowania nowych typów lub rozszerzania istniejących typów, zobacz Rozszerzanie typów obiektów i formatowanie.

Budowania polecenia cmdlet

Po zaimplementowaniu polecenia cmdlet należy zarejestrować je w Windows PowerShell za pośrednictwem Windows PowerShell przystawki. Aby uzyskać więcej informacji na temat rejestrowania cmdlet, zobacz How to Register Cmdlets, Providers, and Host Applications(Jak rejestrować polecenia cmdlet, dostawców i aplikacje hosta).

Testowanie polecenia cmdlet

Po zarejestrowaniu polecenia cmdlet w programie PowerShell można je przetestować, uruchamiając je w wierszu polecenia. Przetestujmy przykładowe polecenie cmdlet Get-Proc, aby sprawdzić, czy zgłasza błąd:

  • Uruchom program PowerShell i użyj Get-Proc cmdlet , aby pobrać procesy o nazwie "TEST".

    get-proc -name test
    

    Wyświetlone są następujące dane wyjściowe.

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

Zobacz też

Dodawanie parametrów, które przetwarzają dane wejściowe potoku

Dodawanie parametrów, które przetwarzają Command-Line danych wejściowych

Tworzenie pierwszego polecenia cmdlet

Rozszerzanie typów obiektów i formatowanie

Jak rejestrować polecenia cmdlet, dostawców i aplikacje hosta

Dokumentacja programu Windows PowerShell

Przykłady poleceń cmdlet