Windows PowerShellWMI との関係

Don Jones

これまで VBScript を扱う際に全面的に頼りにしていたテクノロジの 1 つが WMI (Windows Management Instrumentation) でした。興味深いことに、Windows PowerShell は WMI と密接な関係があります。これは技術的な意味だけではありません。Windows PowerShell を設計した Jeffrey Snover は、Wmic.exe の作成においても中心的存在でした。

Wmic.exe は、Windows Server® 2003 時代のコマンド ライン ツールであり、WMI の操作に使用します。Wmic.exe は、多くの点で Windows PowerShell™ の前身であり、ほぼ同じように機能します (WMIC の詳細については、TechNet Magazine 2006 年 9 月号の John Kelbley の記事 (microsoft.com/technet/technetmag/issues/2006/09/WMIData) を参照してください)。**

Windows PowerShell は WMI をサポートします。WMI のサポートは、シェルの他の機能と同様に、オブジェクト ベースの一貫した方法で提供されます。そのため、WMI は VBScript などの以前のテクノロジに比べて非常に簡単に習得および使用できます。特に、特定の問題について習得や使用を行う場合はその傾向が顕著です。

WMI 入門

スクリプト関連の書籍や記事を読むと、WMI に関する記載がないことはまずありません。ただし、実際の WMI を使用することに夢中になりすぎ、WMI が内部的にどのように構築されたかを忘れがちです。WMI の構造は、Windows PowerShell における WMI の機能にとって特に重要です。

WMI は、主に、Windows® オペレーティング システムや、その他の Windows ベースのハードウェア製品やソフトウェア製品の管理情報を表すクラスを編成した 1 つのシステムです。実際に、クラスは、ある特定のソフトウェア コンポーネントやハードウェア コンポーネントが保持するプロパティや機能を抽象的に表したものにすぎません。たとえば、論理ディスクのクラスは、シリアル番号、一定の記憶域容量、使用可能な容量などを持ったデバイスを表します。一方、Windows サービスを表すクラスは、そのサービスに名前が付いていること、そのサービスを開始または停止できること、その現在状態などを示します。

WMI のクラスは、WMI で管理できるすべての内容を表します。クラスがないものについては、WMI ではそのコンポーネントを管理できません。マイクロソフトでは、主要な Windows WMI クラス (msdn2.microsoft.com/aa394554.aspx) のドキュメントを用意しています。また、インターネット インフォメーション サービスや SQL Server™ などの製品では、個別に WMI クラスのドキュメントが作成されています。

あまりにも多くのクラスが存在するため、WMI では、こうしたクラスが名前空間の階層にまとめられています。たとえば、主要な Windows OS クラスを格納している名前空間は root\cimv2 という名前です。それに対して、Microsoft IIS 6.0 はそのクラスを root\MicrosoftIISv2 に格納します。都合のいいことに、root\cimv2 名前空間は WMI の既定の名前空間です。そのためこの名前空間の設定は Windows PowerShell で共有されるため、こうした主要クラスを簡単に使用できるようになっています。

"インスタンス" は、クラスの実体です。たとえば、コンピュータに論理ディスクが 2 台搭載されている場合は、Win32_LogicalDisk クラスのインスタンスが 2 つ存在します。コンピュータ上で 50 個のサービスが実行されていれば、WMI では Win32_Service クラスのインスタンスが 50 個確認されます。WMI の操作とは、基本的には、1 つ以上のインスタンスの提供を WMI にリクエストした後に、インスタンスのプロパティを調べて必要な管理情報を探したり、インスタンスのメソッドを実行して管理上の変更 (サービスの開始や停止など) を行ったりすることです。

WMI は、クライアント サーバー アーキテクチャを使用します。Windows 2000 以降の Windows の各バージョンには、WMI ビルトイン (バージョンが新しいほど、使用可能なクラスの数が増えています) が付属しています。つまり、WMI クライアントと WMI サーバーのどちらのソフトウェアも使用可能です。WMI を使用する場合、実際には、対象のコンピュータ上で実行されている WMI サービスに要求を送信します。その WMI サービスが、指定された WMI インスタンスを取得して返すため、ユーザーはそのインスタンスを操作できます。Windows PowerShell ではこの部分を取り扱います。そのため、インスタンスを要求、取得、および操作するプロセスが簡略化されます。

WMI オブジェクトの取得

WMI クラス インスタンスは大ざっぱに "オブジェクト" と呼ばれているため、こうしたインスタンスを Windows PowerShell で取得する方法が Get-WMIObject コマンドレットであることは不思議ではありません。このコマンドレットには、便利なエイリアス gwmi が用意されており、この記事のほとんどの例に使用します。最も単純な形式は、取得する WMI クラス名を指定して結果を参照するだけです (図 1 参照)。gwmi win32_service を実行すると、Windows PowerShell は、(別のコンピュータを指定していないため) ローカル コンピュータ上の WMI サービスに接続し、(他の名前空間を指定していないため) root\cimv2 名前空間に接続します。Windows PowerShell は、指定したクラスのすべてのインスタンスを取得しました。これらのインスタンスについて特に何も指示しなかったため、インスタンスがテキスト表現に変換されます。つまり、Windows PowerShell は、このようなオブジェクトを取得し、人間である私にわかるようにテキストを生成したのです。

図 1 gwmi win32_service を実行すると、Windows PowerShell は、指定したクラスのすべてのインスタンスを読みやすいテキスト形式で返す

図 1** gwmi win32_service を実行すると、Windows PowerShell は、指定したクラスのすべてのインスタンスを読みやすいテキスト形式で返す **

具体的には、Windows PowerShell は、選択したクラスのプロパティの名前と値を読み取って表示することで、WMI オブジェクトをテキストに変換します。Win32_Service クラスの場合、6 つのプロパティのセットが選択されます。

実際、Windows PowerShell は、この方法で任意のオブジェクトをテキストに変換します。表示されているプロパティの大部分は、Windows PowerShell インストール フォルダにある一連の .format.ps1xml ファイルで定義されています。このような書式定義ファイルは、マイクロソフトによってデジタル署名されています。独自の書式設定ファイルを提供することもできますが、これらのファイルは変更しないことをお勧めします (このトピックについては、今後のコラムで詳しく説明する予定です)。

gwmi コマンドレットを使用すると、コンピュータを調べて、使用できるクラスを見つけることができます。たとえば、gwmi –namespace "root\cimv2" –list を実行すると、その名前空間にあるクラスの全一覧が表示されます。ただし、ローカル コンピュータのクラスが関連するのは、そのコンピュータを管理している場合のみであることに注意してください。リモート コンピュータを管理している場合は、そのシステム上で使用できるクラスについて調べる必要があります。このため、リモート コンピュータに接続するには、gwmi の –computer パラメータを使用します。たとえば、gwmi –namespace "root\cimv2" –list –computer ServerA では、ServerA というリモート コンピュータ上の root\cimv2 名前空間にあるクラスの全一覧が表示されます。

リモート WMI

Windows PowerShell バージョン 1.0 では、gwmi がリモート管理を直接サポートするほぼ唯一のコマンドレットです。これは、主に、リモート コントロールが基になる WMI アーキテクチャに組み込まれているためです。Windows PowerShell は、単にその既存のアーキテクチャを使用しているだけなので、そのアーキテクチャのセキュリティ機能の対象となります。次に例を示します。

C:\> gwmi -namespace “root\cimv2” -computer
mediaserver -list
Get-WmiObject : Access is denied. (Exception
from HRESULT: 0x80070005 (E_ACCESSDENIED))
At line:1 char:5
+ gwmi <<<< -namespace “root\cimv2” -computer
mediaserver -list
PS C:\>

この例では、アクセス許可のない MediaServer というリモート コンピュータへの接続を試みました。管理者にはこのコンピュータの WMI サービスを操作するアクセス許可が必要であり、ローカル ワークステーションの資格情報では不十分であると考えられます。たとえば、信頼関係のない別のドメインにログオンする場合もあれば、権限の低いアカウントを使用してログオンする場合もあります。さいわい、gwmi が –credential パラメータをサポートしているため、WMI 接続には、代わりのユーザー資格情報のセットを指定することができます。次に、非常に簡単な例を示します。

gwmi win32_service –credential mydomain\administrator –computer mediaserver

資格情報 (具体的にはユーザー名) は、"ドメイン\ユーザー名" 形式で指定します。

パスワードを入力する場所がないことに注意してください。パスワードは、Windows PowerShell から要求されます。Windows PowerShell には、コマンド ラインでパスワードを入力する方法が意図的に用意されていません。この方法が用意されていると、スクリプト ファイル内にパスワードをハードコーディングできるようになるためです。これは、確実にセキュリティ上のリスクになります。ただし、この –credential パラメータを使用した別の方法もあります。この方法では、PSCredential という資格情報オブジェクトを前もって作成しておきます。重要なのは、Get-Credential コマンドレットです。

$cred = get-credential mydomain\administrator

これを実行しても、パスワードの確認が求められます。ただし、この場合、作成した資格情報オブジェクトが $cred 変数に格納されます。$cred の内容を確認すると、ユーザー名はわかりますが、パスワードはわかりません。

PS C:\> $cred

UserName
--------
mydomain\adminstrator

その後、その資格情報オブジェクトを何回でも再利用できます。

gwmi win32_service –credential $cred –computer mediaserver

この結果、再利用可能な資格情報オブジェクトを事前に定義することで、リモート コンピュータに対して繰り返し行われる WMI 接続が簡略化されます。ただし、Get-WMIObject コマンドレットでは、現在のところ、認証レベルの指定 (偽装とも呼ばれる) が VBScript と同じ方法ではサポートされていません。詳細については、msdn2.microsoft.com/aa389290.aspx を参照してください。

自動探索

私が Windows PowerShell について気に入っている点の 1 つは、機能に関する安易な妥協がないことです。ここまでは、照会する Win32_Service クラスのプロパティ セットのみを Windows PowerShell がどのように選択するかということだけを示してきました。ところが、シェルではすべてのプロパティにアクセスでき、どのようなプロパティがあるかを示すこともできます。これを行うには、図 2 に示すように、オブジェクトを Get-Member コマンドレット (またはそのエイリアス gm) にパイプ処理するだけです。

図 2 オブジェクトを Get-Member コマンドレットにパイプ処理すると、アクセス可能なメソッドやプロパティが示される

図 2**  オブジェクトを Get-Member コマンドレットにパイプ処理すると、アクセス可能なメソッドやプロパティが示される **(画像を拡大するには、ここをクリックします)

シェルでは、プロパティだけでなく、使用可能なメソッドの一覧も表示されます。つまり、クラスで実行できることを調べるために、必ずしもドキュメントが必要ではありません。クラス自体に、インスタンスの構成の変更、サービスの一時停止、サービスの停止などを行う手段が用意されていることがわかります。

これらのメソッドを使用したり、他のプロパティを表示したりするには、多くの場合、インスタンスを変数に格納するのが最も簡単です。

$server = gwmi win32_operatingsystem
$server.reboot()

このサンプルでは、Win32_OperatingSystem クラスの使用可能なインスタンスのみを取得し (このクラスには、コンピュータごとにインスタンスが 1 つだけあります)、$server 変数に保存します。その後、$server 変数を使用してインスタンスの Reboot メソッドにアクセスし、コンピュータを再起動します。この操作には十分注意してください。

豊富なクエリ言語

VBScript などのテクノロジで WMI を使用したことがあれば、おそらく、WQL (WMI Query Language) で記述したクエリを使用して WMI クラス インスタンスを取得することには慣れているでしょう。構文が SQL に似ているため、指定したクラスのすべてのインスタンスではなく、特定のインスタンス (特定のサービスなど) を簡単に取得できます。さいわい、gwmi を使用すれば、次のようにクエリを指定することもできます。

gwmi –query “select * from win32_service where name=’alerter’”

(Windows PowerShell が正式にリリースされる直前に追加された) この gwmi の構文は非常に便利で、他の目的で開発した複雑な WMI クエリが実に簡単に移行できるようになります。また、通常どおり、Windows PowerShell は、独自のプロパティとメソッドを持つ豊富なオブジェクトを返して、WMI の管理機能に完全にアクセスできるようにします。

今後の WMI

WMI は、今後のバージョンの Windows に向けて開発が継続されるため、新しいクラスや機能が追加されます。また、マイクロソフトの新製品にも引き続き追加されます。ほとんどのマイクロソフト製品では、Windows PowerShell を具体的に対象としたバージョンがまだリリースされていませんが、WMI に接続する機能は大きなメリットの 1 つであり、現在の Windows PowerShell を有益にしている理由の 1 つです。

ここでは、WMI でできることをほんの少し取り上げたにすぎません。それでも、Windows PowerShell について調べて、使用可能な機能を自分で探す気になっていただけたらさいわいです。

Don Jones は SAPIEN Technologies のプロジェクトおよびサービスの責任者であり、『Windows PowerShell: TFM』(SAPIEN Press) の共著者でもあります。**Don に対するお問い合わせについては、彼の Web サイト (www.ScriptingAnswers.com) (英語) を参照してください。

© 2008 Microsoft Corporation and CMP Media, LLC. All rights reserved; 許可なしに一部または全体を複製することは禁止されています.