このトピックでは、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
この方法のオーバーライドは以下の通りです:
System.Management.Automation.PSDriveinfo.Root*メンバーが存在し、データストアへの接続が可能かどうかを確認しましょう。
ドライブを作成し、
New-PSDriveコマンドレットをサポートするために接続メンバーを埋めます。提案されたドライブの System.Management.Automation.PSDriveinfo オブジェクトを検証してください。
System.Management.Automation.PSDriveinfoオブジェクトに、必要なパフォーマンスや信頼性情報を記載したり、使用者に追加データを提供したりしてください。
System.Management.Automation.Provider.CmdletProvider.WriteErrorメソッドで失敗を処理し、その後
nullを返します。このメソッドは、そのメソッドに渡されたドライブ情報またはプロバイダー固有のバージョンのいずれかを返します。
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に登録されたら、コマンドライン上でサポートされたコマンドレットを実行し、派生によって提供されたコマンドレットも含めてテストできます。 サンプルドライブの提供者をテストしてみましょう。
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}オペレーティングシステムの管理ツールの「データソース」部分にアクセスし、データベースのサーバー名(DSN)が存在することを確認してください。 ユーザーDSNテーブルでMS Access Databaseをダブルクリックし、ドライブパス
C:\ps\northwind.mdbを追加します。サンプルドライブプロバイダーを使って新しいドライブを作成します:
New-PSDrive -Name mydb -Root C:\ps\northwind.mdb -PSProvider AccessDb`次のような出力が表示されます。
Name Provider Root CurrentLocation ---- -------- ---- --------------- mydb AccessDB C:\ps\northwind.mdb接続を検証します。 接続はドライブのメンバーとして定義されているので、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 :ドライブを取り外して外装を解除します:
PS> Remove-PSDrive mydb PS> exit