PowerShellの重要な特徴として、ファイルシステムやレジストリ、環境変数など異なるデータソースに対して共通の操作(コマンドレット)が行えるということが挙げられます。
例えば、以下のように「C」ドライブ直下に「New-Item」コマンドレットでファイルを作成できるのと同じ感覚で、
PS c:\> New-Item hoge
「HKLM」ドライブ(HKEY_LOCAL_MACHINE)に移動して、「New-Item」コマンドレットでレジストリキーが作れるといった具合にです。
PS HKLM:\Software > New-Item hoge
これらはプロバイダーという機構によって成り立っています。
ファイルシステムならFileSystemProvider、レジストリならRegistryProvider、環境変数ならEnvironmentProviderと言った具合にそれぞれに対応するプロバイダーが用意されています。
PowerShellには「New-PSDrive」というコマンドレットが用意されています。
このコマンドレットは「PSDrive」というPowerShell上でだけ有効な仮想的なドライブを新規作成するものですが、このコマンドレットのパラメータを見て下さい。
New-PSDrive [-name] [-psProvider] [-root] [-description ] [-scope ] [-credential ]
二つ目の引数に「psProvider」というのがあります。この引数でどのプロバイダーを使ってPSDriveを作成するかを決めるわけです。
例えばFileSystemProviderを使って、「C:\WINDOWS」ディレクトリをルートとする「WIN」ドライブを作る場合、以下のようにします。
PS > New-PSDrive WIN FileSystem C:\WINDOWS
Name Provider Root
---- -------- ----
WIN FileSystem C:\WINDOWS
このようにして、プロバイダーを指定してPSDriveを作成する事ができます。
これらの事からプロバイダーとは、様々な種類のPSDriveを提供するための機構だということがわかります。
開発環境の構築
では、さっそくプロバイダーを作っていきましょう。
開発環境として、
- PowerShell 1.0
- Microsoft Visual Studio 2008 Standard Edition (Visual C# 2008 Expressでも可)
を使用します。
また、プロバイダーの開発には.NET FrameworkとC#に対する基本的な知識が必要になります。
開発用のアセンブリをコピー
プロバイダーの開発には、「System.Management.Automation」というアセンブリが必要になりますが、このアセンブリはGACにのみインストールされているので、ここから取り出す必要があります。
GACにインストールされたアセンブリはWindows Explorerからはコピーができないので、コマンドプロンプトかPowerShellを使ってコピーする必要があります。
「System.Management.Automation.dll」を以下のパスから適当な場所にコピーして下さい。
- C:\WINDOWS\assembly\GAC_MSIL\System.Management.Automation\1.0.0.0__31bf3856ad364e35\System.Management.Automation.dll
プロジェクトの作成
では、プロバイダーの仕組みを学ぶ為に簡単なプロバイダーを作ってみましょう。
Visual Studio 2008を起動して、言語は「Visual C#」で「クラスライブラリ」プロジェクトを作成します。プロジェクト名は「PSHoge」とします。

まずは先程コピーした「System.Management.Automation.dll」アセンブリを参照設定に追加しておきます。
では、プロバイダーを作ってみましょう。
プロバイダーはCmdletProviderクラスを継承して作ります。
しかし、CmdletProviderには必要最低限の機能しか実装されていないので、ここからプロバイダーを実装するのは結構大変です。
なので、通常はCmdletProviderから派生したNavigationCmdletProviderを使用します。
CmdletProviderとNavigationCmdletProviderなどとの継承関係を以下に示します。
プロバイダークラスの継承ツリー
- CmdletProvider
- DriveCmdletProvider
- ItemCmdletProvider
- ContainerCmdletProvider
- SessionStateProviderBase
- AliasProvider
- EnvironmentProvider
- FunctionProvider
- VariableProvider
- NavigationCmdletProvider
- FileSystemProvider
- RegistryProvider
ファイルシステムやレジストリはNavigationCmdletProviderから、環境変数やエイリアスはSessionStateProviderBaseから派生しているのがわかります。
では、NavigationCmdletProviderを継承してプロバイダークラスを作ります。
「HogeProvider.cs」というファイル名でクラスファイルを追加します。
using System;
using System.Management.Automation.Provider;
namespace PSHoge {
[CmdletProvider("Hoge", ProviderCapabilities.ShouldProcess)]
public class HogeProvider : NavigationCmdletProvider {
protected override bool IsValidPath(string path) {
return true;
}
}
}
NavigationCmdletProviderクラスを継承して、IsValidPathメソッドをオーバーライドします。ここではとりあえずtrueを返しておきます。
そして、プロバイダークラスである事を示す為にCmdletProvider属性でマークしています。引数として「Hoge」と「ProviderCapabilities.ShouldProcess」を渡しています。
前者はプロバイダー名で後者はとりあえずこれを指定しておいて下さい。
次にこのプロバイダーをPowerShellにインストールするためのインストーラクラスを作成します。
using System;
using System.Management.Automation;
using System.ComponentModel;
namespace PSHoge {
[RunInstaller(true)]
public class HogeSnapIn : PSSnapIn {
public override string Description {
get { return "テスト用のプロバイダーです。"; }
}
public override string Name {
get { return "Hoge"; }
}
public override string Vendor {
get { return "coma2n"; }
}
}
}
PowerShellのインストーラクラスはPSSnapInクラスから派生させます。Description、Name、Vendorというプロパティをそれぞれ実装する必要があります。
そして、このクラスがインストーラクラスである事を示す為にRunInstaller属性でマークしておきます。
とりあえずここまでで一度PowerShellにこのプロバイダーをインストールしてみましょう。
プロジェクトをビルドして、プロジェクトの出力ディレクトリ(bin\Debug)にコマンドプロンプトで移動して下さい。
以下のコマンドを実行してプロバイダーをインストールします。
PS > InstallUtil.exe PSHoge.dll
正常にインストールが完了したらPowerShellを起動して以下のコマンドを実行します。
PS > Add-PSSnapin Hoge
これでPowerShellにプロバイダーのインストールが完了しました。
あとは前述の「New-PSDrive」コマンドレットを使って、ドライブを新規作成します。
PS > New-PSDrive Hoge Hoge c:\
これで「Hoge」プロバイダーで「Hoge」ドライブを作る事ができました。ルートディレクトリのパスはここでは意味はありませんが、指定する必要があります。
では、試しに「Hoge」ドライブにcdしてみましょう。
Set-Location : プロバイダがこの操作をサポートしていないため、プロバイダの実行が中止されました。
発生場所 行:1 文字:3
+ cd <<<< hoge:
実はこの段階ではまだcdはできません。では次はこれができるようにしてみましょう。
目次