英語で読む

次の方法で共有


Windows PowerShell コンテナー プロバイダーの作成

このトピックでは、多層データ ストアで動作する Windows PowerShell プロバイダーを作成する方法について説明します。 この種類のデータ ストアの場合、ストアの最上位にはルート項目が含まれており、後続の各レベルは子項目のノードと呼ばれます。 ユーザーがこれらの子ノードで作業できるようにすることで、ユーザーはデータ ストアを介して階層的に対話できます。

複数レベルのデータ ストアで動作できるプロバイダーは、Windows PowerShell コンテナー プロバイダーと呼ばれます。 ただし、Windows PowerShell コンテナー プロバイダーは、アイテムが含まれるコンテナーが 1 つ (入れ子になったコンテナーがない) 場合にのみ使用できることに注意してください。 入れ子になったコンテナーがある場合は、Windows PowerShell ナビゲーション プロバイダーを実装する必要があります。 Windows PowerShell ナビゲーション プロバイダーの実装の詳細については、「Windows PowerShell ナビゲーション プロバイダーの作成」を参照してください。

注意

Windows Vista および .NET Framework 3.0 ランタイム コンポーネント用の Microsoft Windows ソフトウェア開発キットを使用して、このプロバイダーの C# ソース ファイル (AccessDBSampleProvider04.cs) をダウンロードできます。 ダウンロード手順については、「Windows PowerShell をインストールして Windows PowerShell SDKをダウンロードする方法」を参照してください。 ダウンロードしたソース ファイルは、<PowerShell Samples> ディレクトリにあります。 その他の Windows PowerShell プロバイダーの実装の詳細については、「Windows PowerShell プロバイダーの設計」を参照してください。

ここで説明する Windows PowerShell コンテナー プロバイダーは、データベースを 1 つのコンテナーとして定義し、データベースのテーブルと行をコンテナーの項目として定義します。

注意事項

この設計では、名前 ID を持つフィールドがあり、フィールドの型が LongInteger であるデータベースを想定していることに注意してください。

Windows PowerShell コンテナー プロバイダー クラスの定義

Windows PowerShell コンテナー プロバイダーは、System.Management.Automation.Provider.ContainerCmdletProvider 基底クラスから派生する .NET クラスを定義する必要があります。 このセクションで説明する Windows PowerShell コンテナー プロバイダーのクラス定義を次に示します。

[CmdletProvider("AccessDB", ProviderCapabilities.None)]
public class AccessDBProvider : ContainerCmdletProvider

このクラス定義では、System.Management.Automation.Provider.CmdletProviderAttribute 属性に 2 つのパラメーターが含まれていることに注意してください。 最初のパラメーターは、Windows PowerShell で使用されるプロバイダーのわかりやすい名前を指定します。 2 番目のパラメーターは、コマンド処理中にプロバイダーが Windows PowerShell ランタイムに公開する Windows PowerShell 固有の機能を指定します。 このプロバイダーでは、Windows PowerShell 固有の機能は追加されません。

基本機能の定義

Windows PowerShell プロバイダーの設計」で説明されているように、System.Management.Automation.Provider.ContainerCmdletProvider クラスは、異なるプロバイダー機能を提供する他のいくつかのクラスから派生します。 そのため、Windows PowerShell コンテナー プロバイダーでは、これらのクラスによって提供されるすべての機能を定義する必要があります。

セッション固有の初期化情報を追加し、プロバイダーによって使用されるリソースを解放するための機能を実装するには、「基本的な Windows PowerShell プロバイダーの作成を参照してください。 ただし、ほとんどのプロバイダー (ここで説明するプロバイダーを含む) では、Windows PowerShell によって提供されるこの機能の既定の実装を使用できます。

データ ストアにアクセスするには、System.Management.Automation.Provider.DriveCmdletProvider 基底クラスのメソッドをプロバイダーが実装する必要があります。 これらのメソッドの実装の詳細については、「Windows PowerShell ドライブ プロバイダーの作成」を参照してください。

アイテムの取得、設定、クリアなどのデータ ストアの項目を操作するには、System.Management.Automation.Provider.ItemCmdletProvider 基底クラスによって提供されるメソッドをプロバイダーが実装する必要があります。 これらのメソッドの実装の詳細については、「Windows PowerShell アイテム プロバイダーの作成」を参照してください。

子項目の取得

子項目を取得するには、Windows PowerShell コンテナー プロバイダーが System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* メソッドをオーバーライドして、Get-ChildItem コマンドレットからの呼び出しをサポートする必要があります。 このメソッドは、データ ストアから子項目を取得し、オブジェクトとしてパイプラインに書き込みます。 コマンドレットの recurse パラメーターが指定されている場合、メソッドは、レベルに関係なく、すべての子を取得します。 recurse パラメーターが指定されていない場合、メソッドは 1 つのレベルの子のみを取得します。

このプロバイダーの System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* メソッドの実装を次に示します。 このメソッドは、パスが Access データベースを示すときにすべてのデータベース テーブルの子項目を取得し、パスがデータ テーブルを示す場合は、そのテーブルの行から子項目を取得します。

protected override void GetChildItems(string path, bool recurse)
{
    // If path represented is a drive then the children in the path are 
    // tables. Hence all tables in the drive represented will have to be
    // returned
    if (PathIsDrive(path))
    {
        foreach (DatabaseTableInfo table in GetTables())
        {
            WriteItemObject(table, path, true);

            // if the specified item exists and recurse has been set then 
            // all child items within it have to be obtained as well
            if (ItemExists(path) && recurse)
            {
                GetChildItems(path + pathSeparator + table.Name, recurse);
            }
        } // foreach (DatabaseTableInfo...
    } // if (PathIsDrive...
    else
    {
        // Get the table name, row number and type of path from the
        // path specified
        string tableName;
        int rowNumber;

        PathType type = GetNamesFromPath(path, out tableName, out rowNumber);

        if (type == PathType.Table)
        {
            // Obtain all the rows within the table
            foreach (DatabaseRowInfo row in GetRows(tableName))
            {
                WriteItemObject(row, path + pathSeparator + row.RowNumber,
                        false);
            } // foreach (DatabaseRowInfo...
        }
        else if (type == PathType.Row)
        {
            // In this case the user has directly specified a row, hence
            // just give that particular row
            DatabaseRowInfo row = GetRow(tableName, rowNumber);
            WriteItemObject(row, path + pathSeparator + row.RowNumber,
                        false);
        }
        else
        {
            // In this case, the path specified is not valid
            ThrowTerminatingInvalidPathException(path);
        }
    } // else
} // GetChildItems

GetChildItems の実装に関する注意事項

System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems*の実装には、次の条件が適用される場合があります。

Get-ChildItem コマンドレットへの動的パラメーターのアタッチ

System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* を呼び出す Get-ChildItem コマンドレットでは、実行時に動的に指定される追加のパラメーターが必要になる場合があります。 これらの動的パラメーターを指定するには、Windows PowerShell コンテナー プロバイダーが System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItemsDynamicParameters* メソッドを実装する必要があります。 このメソッドは、指定されたパスにある項目の動的パラメーターを取得し、コマンドレット クラスまたは System.Management.Automation.RuntimeDefinedParameterDictionary オブジェクトと同様の解析属性を持つプロパティとフィールドを持つオブジェクトを返します。 Windows PowerShell ランタイムは、返されたオブジェクトを使用して、パラメーターを Get-ChildItem コマンドレットに追加します。

この Windows PowerShell コンテナー プロバイダーでは、このメソッドは実装されません。 ただし、次のコードは、このメソッドの既定の実装です。

子項目名の取得

子項目の名前を取得するには、Windows PowerShell コンテナー プロバイダーは、System.Management.Automation.Provider.ContainerCmdletProvider.GetChildNames* メソッドをオーバーライドして、Name パラメーターが指定されている場合に、Get-ChildItem コマンドレットからの呼び出しをサポートする必要があります。 このメソッドは、コマンドレットの returnAllContainers パラメーターが指定されている場合、指定したパスの子項目の名前またはすべてのコンテナーの子項目名を取得します。 子名は、パスのリーフ部分です。 たとえば、パス C:\windows\system32\abc.dll の子名は "abc.dll" です。 ディレクトリ C:\windows\system32 の子名は "system32" です。

このプロバイダーの System.Management.Automation.Provider.ContainerCmdletProvider.GetChildNames* メソッドの実装を次に示します。 指定したパスが Access データベース (ドライブ) を示し、パスがテーブルを示す場合は行番号を示す場合、メソッドはテーブル名を取得します。

protected override void GetChildNames(string path,
                              ReturnContainers returnContainers)
{
    // If the path represented is a drive, then the child items are
    // tables. get the names of all the tables in the drive.
    if (PathIsDrive(path))
    {
        foreach (DatabaseTableInfo table in GetTables())
        {
            WriteItemObject(table.Name, path, true);
        } // foreach (DatabaseTableInfo...
    } // if (PathIsDrive...
    else
    {
        // Get type, table name and row number from path specified
        string tableName;
        int rowNumber;

        PathType type = GetNamesFromPath(path, out tableName, out rowNumber);

        if (type == PathType.Table)
        {
            // Get all the rows in the table and then write out the 
            // row numbers.
            foreach (DatabaseRowInfo row in GetRows(tableName))
            {
                WriteItemObject(row.RowNumber, path, false);
            } // foreach (DatabaseRowInfo...
        }
        else if (type == PathType.Row)
        {
            // In this case the user has directly specified a row, hence
            // just give that particular row
            DatabaseRowInfo row = GetRow(tableName, rowNumber);

            WriteItemObject(row.RowNumber, path, false);
        }
        else
        {
            ThrowTerminatingInvalidPathException(path);
        }
    } // else
} // GetChildNames

GetChildNames の実装に関する注意事項

System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems*の実装には、次の条件が適用される場合があります。

Get-ChildItem コマンドレットへの動的パラメーターのアタッチ (名前)

Get-ChildItem コマンドレット (Name パラメーター) で、実行時に動的に指定される追加のパラメーターが必要な場合があります。 これらの動的パラメーターを指定するには、Windows PowerShell コンテナー プロバイダーが System.Management.Automation.Provider.ContainerCmdletProvider.GetChildNamesDynamicParameters* メソッドを実装する必要があります。 このメソッドは、指定されたパスにある項目の動的パラメーターを取得し、コマンドレット クラスまたは System.Management.Automation.RuntimeDefinedParameterDictionary オブジェクトと同様の解析属性を持つプロパティとフィールドを持つオブジェクトを返します。 Windows PowerShell ランタイムは、返されたオブジェクトを使用して、パラメーターを Get-ChildItem コマンドレットに追加します。

このプロバイダーは、このメソッドを実装しません。 ただし、次のコードは、このメソッドの既定の実装です。

アイテムの名前変更

アイテムの名前を変更するには、Windows PowerShell コンテナー プロバイダーが、Rename-Item コマンドレットからの呼び出しをサポートするために、System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem* メソッドをオーバーライドする必要があります。 このメソッドは、指定したパスにある項目の名前を、指定された新しい名前に変更します。 新しい名前は、常に親項目 (コンテナー) に対する相対名である必要があります。

このプロバイダーは、System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem* メソッドをオーバーライドしません。 ただし、既定の実装は次のとおりです。

RenameItem の実装に関する注意事項

System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem*の実装には、次の条件が適用される場合があります。

Rename-Item コマンドレットへの動的パラメーターのアタッチ

Rename-Item コマンドレットで、実行時に動的に指定される追加のパラメーターが必要な場合があります。 これらの動的パラメーターを指定するには、Windows PowerShell コンテナー プロバイダーが System.Management.Automation.Provider.ContainerCmdletProvider.RenameItemDynamicParameters* メソッドを実装する必要があります。 このメソッドは、指定されたパスにある項目のパラメーターを取得し、コマンドレット クラスまたは System.Management.Automation.RuntimeDefinedParameterDictionary オブジェクトのような解析属性を持つプロパティとフィールドを持つオブジェクトを返します。 Windows PowerShell ランタイムは、返されたオブジェクトを使用して、パラメーターを Rename-Item コマンドレットに追加します。

このコンテナー プロバイダーでは、このメソッドは実装されません。 ただし、次のコードは、このメソッドの既定の実装です。

新しい項目の作成

新しい項目を作成するには、New-Item コマンドレットからの呼び出しをサポートするために、コンテナー プロバイダーが System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* メソッドを実装する必要があります。 このメソッドは、指定したパスにあるデータ項目を作成します。 コマンドレットの type パラメーターには、新しい項目のプロバイダー定義型が含まれています。 たとえば、FileSystem プロバイダーは、値が "file" または "directory" の type パラメーターを使用します。 コマンドレットの newItemValue パラメーターは、新しい項目のプロバイダー固有の値を指定します。

このプロバイダーの System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* メソッドの実装を次に示します。

protected override void NewItem( string path, string type, object newItemValue )
{
    // Create the new item here after
    // performing necessary validations
    //
    // WriteItemObject(newItemValue, path, false);

    // Example
    //
    // if (ShouldProcess(path, "new item"))
    // {
    //      // Create a new item and then call WriteObject
    //      WriteObject(newItemValue, path, false);
    // }

} // NewItem
{
    case 1:
        {
            string name = pathChunks[0];

            if (TableNameIsValid(name))
            {
                tableName = name;
                retVal = PathType.Table;
            }
        }
        break;

    case 2:
        {
            string name = pathChunks[0];

NewItem の実装に関する注意事項

System.Management.Automation.Provider.ContainerCmdletProvider.NewItem*の実装には、次の条件が適用される場合があります。

New-Item コマンドレットへの動的パラメーターのアタッチ

New-Item コマンドレットで、実行時に動的に指定される追加のパラメーターが必要な場合があります。 これらの動的パラメーターを指定するには、コンテナー プロバイダーが System.Management.Automation.Provider.ContainerCmdletProvider.NewItemDynamicParameters* メソッドを実装する必要があります。 このメソッドは、指定されたパスにある項目のパラメーターを取得し、コマンドレット クラスまたは System.Management.Automation.RuntimeDefinedParameterDictionary オブジェクトのような解析属性を持つプロパティとフィールドを持つオブジェクトを返します。 Windows PowerShell ランタイムは、返されたオブジェクトを使用して、パラメーターを New-Item コマンドレットに追加します。

このプロバイダーは、このメソッドを実装しません。 ただし、次のコードは、このメソッドの既定の実装です。

アイテムの削除

アイテムを削除するには、Windows PowerShell プロバイダーは、Remove-Item コマンドレットからの呼び出しをサポートするために、System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItem* メソッドをオーバーライドする必要があります。 このメソッドは、指定したパスにあるデータ ストアから項目を削除します。 Remove-Item コマンドレットの recurse パラメーターが trueに設定されている場合、メソッドはレベルに関係なくすべての子項目を削除します。 パラメーターが falseに設定されている場合、メソッドは指定したパスにある 1 つの項目のみを削除します。

このプロバイダーは、アイテムの削除をサポートしていません。 ただし、次のコードは、System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItem*の既定の実装です。

RemoveItem の実装に関する注意事項

System.Management.Automation.Provider.ContainerCmdletProvider.NewItem*の実装には、次の条件が適用される場合があります。

Remove-Item コマンドレットへの動的パラメーターのアタッチ

Remove-Item コマンドレットで、実行時に動的に指定される追加のパラメーターが必要な場合があります。 これらの動的パラメーターを指定するには、コンテナー プロバイダーが、これらのパラメーターを処理するために System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItemDynamicParameters* メソッドを実装する必要があります。 このメソッドは、指定されたパスにある項目の動的パラメーターを取得し、コマンドレット クラスまたは System.Management.Automation.RuntimeDefinedParameterDictionary オブジェクトと同様の解析属性を持つプロパティとフィールドを持つオブジェクトを返します。 Windows PowerShell ランタイムは、返されたオブジェクトを使用して、パラメーターを Remove-Item コマンドレットに追加します。

このコンテナー プロバイダーでは、このメソッドは実装されません。 ただし、次のコードは、System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItemDynamicParameters*の既定の実装です。

子項目のクエリ

指定したパスに子項目が存在するかどうかを確認するには、Windows PowerShell コンテナー プロバイダーは、System.Management.Automation.Provider.ContainerCmdletProvider.HasChildItems* メソッドをオーバーライドする必要があります。 このメソッドは、項目に子がある場合は true を返し、それ以外の場合は false 返します。 null または空のパスの場合、このメソッドはデータ ストア内のすべての項目を子と見なし、trueを返します。

System.Management.Automation.Provider.ContainerCmdletProvider.HasChildItems* メソッドのオーバーライドを次に示します。 ChunkPath ヘルパー メソッドによって作成されたパス 部分が 2 つ以上ある場合、データベース コンテナーとテーブル コンテナーのみが定義されているため、このメソッドは falseを返します。 このヘルパー メソッドの詳細については、「Windows PowerShell アイテム プロバイダーの作成」で説明されている ChunkPath メソッドを参照してください。

protected override bool HasChildItems( string path )
{
    return false;
} // HasChildItems
        ErrorCategory.InvalidOperation, tableName));
}

return results;

HasChildItems の実装に関する注意事項

System.Management.Automation.Provider.ContainerCmdletProvider.HasChildItems*の実装には、次の条件が適用される場合があります。

アイテムのコピー

項目をコピーするには、Copy-Item コマンドレットからの呼び出しをサポートするために、コンテナー プロバイダーが System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem メソッドを実装する必要があります。 このメソッドは、コマンドレットの path パラメーターで示される場所から、copyPath パラメーターで示される場所にデータ項目をコピーします。 recurse パラメーターが指定されている場合、メソッドはすべてのサブコンテナーをコピーします。 パラメーターが指定されていない場合、メソッドは 1 つのレベルの項目のみをコピーします。

このプロバイダーは、このメソッドを実装しません。 ただし、次のコードは、System.Management.Automation.Provider.ContainerCmdletProvider.CopyItemの既定の実装です。

CopyItem の実装に関する注意事項

System.Management.Automation.Provider.ContainerCmdletProvider.CopyItemの実装には、次の条件が適用される場合があります。

Copy-Item コマンドレットへの動的パラメーターのアタッチ

Copy-Item コマンドレットで、実行時に動的に指定される追加のパラメーターが必要な場合があります。 これらの動的パラメーターを指定するには、Windows PowerShell コンテナー プロバイダーが、これらのパラメーターを処理するために System.Management.Automation.Provider.ContainerCmdletProvider.CopyItemDynamicParameters* メソッドを実装する必要があります。 このメソッドは、指定されたパスにある項目のパラメーターを取得し、コマンドレット クラスまたは System.Management.Automation.RuntimeDefinedParameterDictionary オブジェクトのような解析属性を持つプロパティとフィールドを持つオブジェクトを返します。 Windows PowerShell ランタイムは、返されたオブジェクトを使用して、パラメーターを Copy-Item コマンドレットに追加します。

このプロバイダーは、このメソッドを実装しません。 ただし、次のコードは、System.Management.Automation.Provider.ContainerCmdletProvider.CopyItemDynamicParameters*の既定の実装です。

コード サンプル

完全なサンプル コードについては、AccessDbProviderSample04 コード サンプルを参照してください。

Windows PowerShell プロバイダーの構築

コマンドレット、プロバイダー、およびホスト アプリケーションを登録する方法」を参照してください。

Windows PowerShell プロバイダーのテスト

Windows PowerShell プロバイダーが Windows PowerShell に登録されている場合は、コマンド ラインでサポートされているコマンドレットを実行してテストできます。 次の出力例では架空の Access データベースが使用されていることに注意してください。

  1. Get-ChildItem コマンドレットを実行して、Access データベースの Customers テーブルから子項目の一覧を取得します。

    Get-ChildItem mydb:customers
    

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

    PSPath        : AccessDB::customers
    PSDrive       : mydb
    PSProvider    : System.Management.Automation.ProviderInfo
    PSIsContainer : True
    Data          : System.Data.DataRow
    Name          : Customers
    RowCount      : 91
    Columns       :
    
  2. Get-ChildItem コマンドレットをもう一度実行して、テーブルのデータを取得します。

    (Get-ChildItem mydb:customers).Data
    

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

    TABLE_CAT   : C:\PS\northwind
    TABLE_SCHEM :
    TABLE_NAME  : Customers
    TABLE_TYPE  : TABLE
    REMARKS     :
    
  3. 次に、Get-Item コマンドレットを使用して、データ テーブルの行 0 にある項目を取得します。

    Get-Item mydb:\customers\0
    

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

    PSPath        : AccessDB::customers\0
    PSDrive       : mydb
    PSProvider    : System.Management.Automation.ProviderInfo
    PSIsContainer : False
    Data          : System.Data.DataRow
    RowNumber     : 0
    
  4. Get-Item を再利用して、行 0 の項目のデータを取得します。

    (Get-Item mydb:\customers\0).Data
    

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

    CustomerID   : 1234
    CompanyName  : Fabrikam
    ContactName  : Eric Gruber
    ContactTitle : President
    Address      : 4567 Main Street
    City         : Buffalo
    Region       : NY
    PostalCode   : 98052
    Country      : USA
    Phone        : (425) 555-0100
    Fax          : (425) 555-0101
    
  5. 次に、New-Item コマンドレットを使用して、既存のテーブルに行を追加します。 Path パラメーターは、行への完全なパスを指定し、テーブル内の既存の行数より大きい行番号を示す必要があります。 Type パラメーターは、追加する項目の種類を指定する Row を示します。 最後に、Value パラメーターは、行の列値のコンマ区切りのリストを指定します。

    New-Item -Path mydb:\Customers\3 -ItemType "Row" -Value "3,CustomerFirstName,CustomerLastName,CustomerEmailAddress,CustomerTitle,CustomerCompany,CustomerPhone, CustomerAddress,CustomerCity,CustomerState,CustomerZip,CustomerCountry"
    
  6. 次のように、新しい項目操作の正確性を確認します。

    PS mydb:\> cd Customers
    PS mydb:\Customers> (Get-Item 3).Data
    

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

    ID        : 3
    FirstName : Eric
    LastName  : Gruber
    Email     : ericgruber@fabrikam.com
    Title     : President
    Company   : Fabrikam
    WorkPhone : (425) 555-0100
    Address   : 4567 Main Street
    City      : Buffalo
    State     : NY
    Zip       : 98052
    Country   : USA
    

こちらもご覧ください

Windows PowerShell プロバイダーの作成

Windows PowerShell プロバイダーの の設計

アイテムの実装 Windows PowerShell プロバイダー

ナビゲーション Windows PowerShell プロバイダー の実装の

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

Windows PowerShell SDK の

Windows PowerShell プログラマ ガイド