終了しないエラーのレポートをコマンドレットに追加する

コマンドレットは、System.Management.Automation.Cmdlet.WriteErrorメソッドを呼び出すことによって、不変エラーを報告できます。また、現在の入力オブジェクトまたはそれ以上の受信パイプライン オブジェクトで引き続き操作できます。 このセクションでは、入力処理メソッドから非確認エラーを報告するコマンドレットを作成する方法について説明します。

非終端エラー (および終了エラー) の場合、コマンドレットはエラーを識別する System.Management.Automation.ErrorRecord オブジェクトを渡す必要があります。 各エラー レコードは、"エラー識別子" と呼ばれる一意の文字列によって識別されます。 識別子に加えて、各エラーのカテゴリは 、System.Management.Automation.ErrorCategory 列挙体によって定義された定数によって指定されます。 ユーザーは、変数を "CategoryView" に設定することで、カテゴリに基 $ErrorView づいてエラーを表示できます。

エラー レコードの詳細については、「エラー レコードのWindows PowerShellを参照してください

コマンドレットの定義

コマンドレットの作成の最初の手順は、常にコマンドレットに名前を付け、コマンドレットを実装する .NET クラスを宣言します。 このコマンドレットはプロセス情報を取得します。そのため、ここで選択した動詞名は "Get" です。 (情報を取得できるほとんどすべての種類のコマンドレットは、コマンド ライン入力を処理できます)。承認されたコマンドレット動詞の詳細については、「コマンドレット動詞名」 を参照してください

このコマンドレットの定義を次に示 Get-Proc します。 この定義の詳細については、「最初のコマンドレット の作成」を参照してください

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

パラメーターの定義

必要に応じて、コマンドレットで入力を処理するパラメーターを定義する必要があります。 このGet-Procコマンドレットでは、「 入力 を処理するパラメーターの追加」の説明に従って Name Command-Line定義します

このコマンドレットの Name パラメーターのパラメーター宣言を次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

入力処理メソッドのオーバーライド

すべてのコマンドレットは 、System.Management.Automation.Cmdlet クラスによって提供される入力処理メソッドの少なくとも 1 つをオーバーライドする必要があります。 これらのメソッドについては、「最初のコマンドレットの 作成」を参照してください

注意

コマンドレットでは、各レコードを可能な限り個別に処理する必要があります。

この Get-Proc、System.Management.Automation.Cmdlet.ProcessRecord メソッドをオーバーライドして、ユーザーまたはスクリプトによって提供される入力の Name パラメーターを処理します。 このメソッドは、要求されたプロセス名ごとにプロセスを取得します。名前が指定されている場合は、すべてのプロセスを取得します。 このオーバーライドの詳細については、「最初のコマンドレット の作成」を参照してください

エラーを報告する際の注意

エラー の書き込み時にコマンドレットが渡す System.Management.Automation.ErrorRecord オブジェクトには、そのコアで例外が必要です。 使用する例外を決定する場合は、.NET のガイドラインに従います。 基本的に、エラーが既存の例外と意味的に同じ場合、コマンドレットでは、その例外を使用するか、例外から派生させる必要があります。 それ以外の場合は、System.Exception クラスから直接新しい例外または例外階層 を派生させる必要 があります。

(ErrorRecord クラスの FullyQualifiedErrorId プロパティを介してアクセスされる) エラー識別子を作成する場合は、次のことに念頭に置きます。

  • 診断目的の文字列を使用して、完全修飾識別子を検査するときに、エラーの原因とエラーの原因を特定できます。

  • 整形式の完全修飾エラー識別子は次のようになります。

    CommandNotFoundException,Microsoft.PowerShell.Commands.GetCommandCommand

前の例では、エラー識別子 (最初のトークン) によってエラーの名前が指定され、残りの部分はエラーの発生場所を示しています。

  • より複雑なシナリオの場合、エラー識別子は、検査時に解析できるドット区切りのトークンになります。 これにより、エラー識別子とエラー カテゴリの部分に分岐しすぎる可能性があります。

コマンドレットは、特定のエラー識別子を別のコード パスに割り当てる必要があります。 エラー識別子の割り当てについては、次の情報に注意してください。

  • エラー識別子は、コマンドレットのライフ サイクルを通して一定の状態を維持する必要があります。 コマンドレットのバージョン間でエラー識別子のセマンティクスを変更しない。
  • 報告されるエラーに非常に対応するエラー識別子にテキストを使用します。 空白や句読点は使用しない。
  • 再現可能なエラー識別子のみをコマンドレットで生成します。 たとえば、プロセス識別子を含む識別子を生成すべきではありません。 エラー識別子は、同じ問題が発生している他のユーザーが見た識別子に対応している場合にのみ、ユーザーに役立ちます。

ハンドルされない例外は、次の条件では PowerShell によってキャッチされません。

  • コマンドレットによって新しいスレッドが作成され、そのスレッドで実行されているコードがハンドルされない例外をスローした場合、PowerShell はエラーをキャッチし、プロセスを終了します。
  • オブジェクトのデストラクターまたは Dispose メソッドにハンドルされない例外が発生するコードがある場合、PowerShell はエラーをキャッチし、プロセスを終了します。

非確認エラーの報告

入力処理メソッドの 1 つでも 、System.Management.Automation.Cmdlet.WriteError メソッドを使用して、非確認エラーを出力ストリームに報告できます。

System.Management.Automation.Cmdlet.ProcessRecordメソッドのオーバーライド内からのSystem.Management.Automation.Cmdlet.WriteErrorの呼び出しを示す、この Get-Proc コマンドレットのコード例を次に示します。 この場合、コマンドレットが指定したプロセス識別子のプロセスを見つからない場合、呼び出しが行されます。

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
  }

非解決エラーの書き込みについて覚えておく必要がある

不特定のエラーの場合、コマンドレットは特定の入力オブジェクトごとに特定のエラー識別子を生成する必要があります。

コマンドレットでは、多くの場合、非解決エラーによって生成される PowerShell アクションを変更する必要があります。 これを行うには、 パラメーターと パラメーター ErrorAction を定義 ErrorVariable します。 パラメーターを定義する場合、コマンドレットにはユーザー オプション ErrorAction System.Management.Automation.ActionPreferenceが表示されます。また、 変数を設定してアクションに直接影響を与 $ErrorActionPreference えすることもできます。

コマンドレットは、 の設定の影響を受けない パラメーターを使用して、変数に非確認 ErrorVariable エラーを保存できます ErrorAction 。 エラーは、変数名の前にプラス記号 (+) を追加することで、既存のエラー変数に追加できます。

コード サンプル

完全な C# サンプル コードについては 、「GetProcessSample04 サンプル」を参照してください

オブジェクトの種類と書式設定を定義する

PowerShell は、.NET オブジェクトを使用してコマンドレット間で情報を渡します。 そのため、コマンドレットで独自の型を定義する必要がある場合や、別のコマンドレットによって提供される既存の型を拡張する必要がある場合があります。 新しい型の定義または既存の型の拡張の詳細については、「オブジェクト型の拡張」および「書式設定」 を参照してください

コマンドレットの構築

コマンドレットを実装した後、 スナップインを使用して、Windows PowerShellにWindows PowerShellする必要があります。 コマンドレットの登録の詳細については、「コマンドレット、プロバイダー、およびホスト アプリケーションを登録する方法」 を参照してください

コマンドレットのテスト

コマンドレットが PowerShell に登録されている場合は、コマンド ラインで実行してテストできます。 コマンドレットのサンプルをテストGet-Proc、エラーが報告されるかどうかを確認します。

  • PowerShell を起動し、Get-Proc コマンドレットを使用して、"TEST" という名前のプロセスを取得します。

    get-proc -name test
    

    次のような出力が表示されます。

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

参照

パイプライン入力を処理するパラメーターを追加する

入力を処理するCommand-Line追加

最初のコマンドレットの作成

オブジェクト型の拡張と書式設定

コマンドレット、プロバイダー、およびホスト アプリケーションを登録する方法

Windows PowerShell リファレンス

コマンドレット サンプル