次の方法で共有


Windows PowerShellドライブプロバイダーの作成

このトピックでは、Windows PowerShellドライブを通じてデータストアにアクセスする方法を提供するWindowsのPowerShellドライブプロバイダーの作成方法について説明します。 この種のプロバイダーはWindows PowerShellドライブプロバイダーとも呼ばれます。 プロバイダーが使用するWindows PowerShellドライブはデータストアへの接続手段を提供します。

ここで説明するWindowsのPowerShellドライブプロバイダーは、Microsoft Accessデータベースへのアクセスを提供します。 このプロバイダーの場合、Windows PowerShellドライブはデータベースを表し(ドライブプロバイダーに任意の数のドライブを追加可能)、ドライブの最上位コンテナはデータベース内のテーブル、コンテナの項目はテーブル内の行を表します。

Windows PowerShell プロバイダークラスの定義

ドライブプロバイダーは System.Management.Automation.Provider.DriveCmdletProvider ベースクラスから派生した.NETクラスを定義しなければなりません。 このドライブプロバイダーのクラス定義は以下の通りです:

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

この例では、 System.Management.Automation.Provider.CmdletProviderAttribute 属性が、プロバイダのユーザーフレンドリーな名前と、コマンド処理中にプロバイダーがWindows PowerShellランタイムに公開するWindows PowerShell固有の能力を指定します。 プロバイダー能力の可能な値は、 System.Management.Automation.Provider.ProviderCapabilities 列挙によって定義されます。 このドライブプロバイダーはこれらの機能をサポートしていません。

基本機能の定義

Windows PowerShell Providerを設計する」で説明されているように、 System.Management.Automation.Provider.DriveCmdletProvider クラスは、プロバイダの初期化および初期化解除に必要なメソッドを定義する System.Management.Automation.Provider.CmdletProvider のベースクラスから派生しています。 セッション固有の初期化情報の追加や、プロバイダで使用されるリソースの解放機能の実装については、「 Basic Windows PowerShell Providerの作成」を参照してください。 しかし、ほとんどのプロバイダー(ここで説明するプロバイダーを含む)は、Windows PowerShellが提供するこの機能のデフォルト実装を使用できます。

ドライブステート情報の作成

すべてのWindows PowerShellプロバイダーはステートレスと見なされており、ドライブプロバイダーはWindows PowerShellランタイムがプロバイダーを呼び出す際に必要とする状態情報を作成する必要があります。

このドライブプロバイダーの場合、状態情報にはドライブ情報の一部として保持されるデータベースへの接続が含まれます。 以下は、この情報がドライブを記述する System.Management.Automation.PSDriveinfo オブジェクトにどのように保存されているかを示すコードです:

internal class AccessDBPSDriveInfo : PSDriveInfo
{
    private OdbcConnection connection;

    /// <summary>
    /// ODBC connection information.
    /// </summary>
    public OdbcConnection Connection
    {
        get { return connection; }
        set { connection = value; }
    }

    /// <summary>
    /// Constructor that takes one argument
    /// </summary>
    /// <param name="driveInfo">Drive provided by this provider</param>
    public AccessDBPSDriveInfo(PSDriveInfo driveInfo)
        : base(driveInfo)
    { }

} // class AccessDBPSDriveInfo

ドライブの作成

Windows PowerShellランタイムでドライブを作成させるには、ドライブプロバイダーが System.Management.Automation.Provider.DriveCmdletProvider.NewDrive* メソッドを実装する必要があります。 以下のコードは、このドライブプロバイダーに対する System.Management.Automation.Provider.DriveCmdletProvider.NewDrive* メソッドの実装を示しています。

      protected override PSDriveInfo NewDrive(PSDriveInfo drive)
      {
          // check if drive object is null
          if (drive == null)
          {
              WriteError(new ErrorRecord(
                  new ArgumentNullException("drive"), 
                  "NullDrive",
                  ErrorCategory.InvalidArgument, 
                  null)
              );
           
              return null;
          }
       
          // check if drive root is not null or empty
          // and if its an existing file
          if (String.IsNullOrEmpty(drive.Root) || (File.Exists(drive.Root) == false))
          {
              WriteError(new ErrorRecord(
                  new ArgumentException("drive.Root"), 
                  "NoRoot",
                  ErrorCategory.InvalidArgument, 
                  drive)
              );

              return null;
          }

          // create a new drive and create an ODBC connection to the new drive
          AccessDBPSDriveInfo accessDBPSDriveInfo = new AccessDBPSDriveInfo(drive);

          OdbcConnectionStringBuilder builder = new OdbcConnectionStringBuilder();

          builder.Driver = "Microsoft Access Driver (*.mdb)";
          builder.Add("DBQ", drive.Root);
         
          OdbcConnection conn = new OdbcConnection(builder.ConnectionString);
          conn.Open();
          accessDBPSDriveInfo.Connection = conn;

          return accessDBPSDriveInfo;
      } // NewDrive

この方法のオーバーライドは以下の通りです:

NewDriveへの動的パラメータの付与

ドライブプロバイダーがサポートしている New-PSDrive コマンドレットは追加のパラメータを必要とする場合があります。 これらの動的パラメータをコマンドレットに付けるために、プロバイダーは System.Management.Automation.Provider.DriveCmdletProvider.NewDriveDynamicParameters* メソッドを実装します。 このメソッドは、コマンドレットクラスや System.Management.Automation.RuntimeDefinedParameterDictionary オブジェクトに似た解析属性を持つプロパティやフィールドを持つオブジェクトを返します。

このドライブプロバイダーはこの方法を上書きしません。 しかし、以下のコードはこのメソッドのデフォルトの実装を示しています:

ドライブの取り外し

データベース接続を閉じるには、ドライブプロバイダーが System.Management.Automation.Provider.DriveCmdletProvider.RemoveDrive* メソッドを実装する必要があります。 この方法は、プロバイダー固有の情報をクリーンアップした後、ドライブとの接続を閉じます。

以下のコードは、このドライブプロバイダーに対する System.Management.Automation.Provider.DriveCmdletProvider.RemoveDrive* メソッドの実装を示しています。

protected override PSDriveInfo RemoveDrive(PSDriveInfo drive)
{
    // check if drive object is null
    if (drive == null)
    {
        WriteError(new ErrorRecord(
            new ArgumentNullException("drive"), 
            "NullDrive",
            ErrorCategory.InvalidArgument, 
            drive)
        );

       return null;
    }

    // close ODBC connection to the drive
    AccessDBPSDriveInfo accessDBPSDriveInfo = drive as AccessDBPSDriveInfo;

    if (accessDBPSDriveInfo == null)
    {
        return null;
    }
    accessDBPSDriveInfo.Connection.Close();
  
    return accessDBPSDriveInfo;
} // RemoveDrive

ドライブを取り外し可能であれば、メソッドは drive パラメータを通じてメソッドに渡された情報を返すべきです。 ドライブを取り外せない場合は、そのメソッドは例外を書き込み、その後 null返します。 プロバイダーがこのメソッドを上書きしなければ、デフォルトの実装は入力として渡されたドライブ情報を返すだけです。

デフォルトドライブの初期化

ドライブプロバイダーは System.Management.Automation.Provider.DriveCmdletProvider.InitializeDefaultDrives* メソッドを実装してドライブをマウントしています。 例えば、Active Directoryプロバイダーは、コンピュータがドメインに結合されている場合、デフォルトのネーミングコンテキスト用にドライブをマウントすることがあります。

このメソッドは、初期化されたドライブに関する情報の集合、または空のコレクションを返します。 このメソッドの呼び出しは、Windows PowerShellランタイムが System.Management.Automation.Provider.CmdletProvider.Start* メソッドを呼び出してプロバイダーを初期化した後に行われます。

このドライブプロバイダーは System.Management.Automation.Provider.DriveCmdletProvider.InitializeDefaultDrives* メソッドを上書きしません。 しかし、以下のコードはデフォルトの実装を示しており、空のドライブコレクションを返します。

InitializeDefaultDrivesの実装について覚えておくべきこと

すべてのドライブプロバイダーは、ユーザーが発見しやすくなるためにルートドライブをマウントすべきです。 ルートドライブは他のマウントドライブのルートとして使われる場所をリストアップしているかもしれません。 例えば、Active Directoryプロバイダーはルートの分散システム環境(DSE)上の namingContext 属性に記載されたネーミングコンテキストを一覧にしたドライブを作成することがあります。 これにより、ユーザーは他のドライブのマウントポイントを発見できます。

コード サンプル

完全なサンプルコードについては、 AccessDbProviderSample02 Code Sampleをご覧ください。

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

Windows PowerShellプロバイダーがWindows PowerShellに登録されたら、コマンドライン上でサポートされたコマンドレットを実行し、派生によって提供されたコマンドレットも含めてテストできます。 サンプルドライブの提供者をテストしてみましょう。

  1. Get-PSProviderコマンドレットを実行して、AccessDBドライブプロバイダーが存在することを確認するためにプロバイダーのリストを取得します。

    追伸>Get-PSProvider

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

    Name                 Capabilities                  Drives
    ----                 ------------                  ------
    AccessDB             None                          {}
    Alias                ShouldProcess                 {Alias}
    Environment          ShouldProcess                 {Env}
    FileSystem           Filter, ShouldProcess         {C, Z}
    Function             ShouldProcess                 {function}
    Registry             ShouldProcess                 {HKLM, HKCU}
    
  2. オペレーティングシステムの管理ツール「データソース」部分にアクセスし、データベースのサーバー名(DSN)が存在することを確認してください。 ユーザーDSNテーブルでMS Access Databaseをダブルクリックし、ドライブパスC:\ps\northwind.mdbを追加します。

  3. サンプルドライブプロバイダーを使って新しいドライブを作成します:

    New-PSDrive -Name mydb -Root C:\ps\northwind.mdb -PSProvider AccessDb`
    

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

    Name     Provider     Root                   CurrentLocation
    ----     --------     ----                   ---------------
    mydb     AccessDB     C:\ps\northwind.mdb
    
  4. 接続を検証します。 接続はドライブのメンバーとして定義されているので、Get-PDDrive コマンドレットを使って確認できます。

    ユーザーはまだドライブとしてプロバイダーとやり取りできません。プロバイダーはそのやり取りのためにコンテナ機能を必要としているからです。 詳細については、「 Windows PowerShellコンテナプロバイダーの作成」をご覧ください。

    追伸> (Get-PSDrive mydb)。接続

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

    ConnectionString  : Driver={Microsoft Access Driver (*.mdb)};DBQ=C:\ps\northwind.mdb
    ConnectionTimeout : 15
    Database          : C:\ps\northwind
    DataSource        : ACCESS
    ServerVersion     : 04.00.0000
    Driver            : odbcjt32.dll
    State             : Open
    Site              :
    Container         :
    
  5. ドライブを取り外して外装を解除します:

    PS> Remove-PSDrive mydb
    PS> exit
    

こちらもご覧ください

Windows PowerShell プロバイダーの作成

Windows PowerShellプロバイダーを設計する

基本的なWindowsPowerShellプロバイダーの作成