次の方法で共有


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

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

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

エラー レコードの詳細については、「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 定義します。

この Get-Proc コマンドレットの Name パラメーターのパラメーター宣言を次に示します。

[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 はエラーをキャッチせず、プロセスを終了します。

終了しないエラーの報告

入力処理メソッドのいずれかを使用すると、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 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
  }

終了しないエラーの書き込みについて覚えておく必要があります

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

コマンドレットは、多くの場合、終了しないエラーによって生成される 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
    

こちらもご覧ください