[PS]WMIの取り扱いについて
暫く更新が滞っていました。私事で忙しかったせいですが、今回はPowerShellとWMIで気がついた点を記載します。
Windows Vistaを使ってPowerShellでインストールされたソフトウェアの一覧を表示しようとして、WMIのWin32_Productクラスを使ってみました。
PS (1) >Get-WmiObject Win32_Product
Get-WmiObject : エラーです
発生場所 行:1 文字:14
+ Get-WmiObject <<<< Win32_Product
このようにエラーになってしまいました。一部のソフトウェアが表示される場合もありますが、必ず「Get-WmiObject : エラーです」となってしまいます。色々と調べていくと、Windows Vista のWMIのWin32_Productクラスのバグらしいということが判明しました。この情報はネットニュースのpowershellの中にありました。この内容を見ると既知のバグでVista SP1で修正される予定だと書かれています。じゃあ、他の方法を使わないとWindows Vistaでインストール済みのソフトウェアの一覧を取得できないことになります。で思いついたのが
- レジストリを列挙する。
- Windows Installer APIを使用する。
という方法です。今回は、Windows Installer APIを使用してみたいと思います。
PS (2) >$wi = New-Object -ComObject WindowsInstaller.Installer
PS (3) >$wi | Get-Member
TypeName: System.__ComObject
Name MemberType Definition
---- ---------- ----------
CreateObjRef Method System.Runtime.Remoting.ObjRef CreateObjRef(
Type requestedType)
Equals Method System.Boolean Equals(Object obj)
GetHashCode Method System.Int32 GetHashCode()
GetLifetimeService Method System.Object GetLifetimeService()
GetType Method System.Type GetType()
InitializeLifetimeService Method System.Object InitializeLifetimeService()
ToString Method System.String ToString()
このようにWindows Installer のCOMオブジェクトには、何故か実装されているはずのメンバーが見当たりません。何故かなぁと思って調べていくと、タイプライブラリにcoclassが定義されていないようです。このためにNew-Objectコマンドレットでは、プロパティやメソッドをマップできないようです。解決策はないのかなと思って調べていくと、Abhishek's PowerShell Blogが見つかりました。この内容を参考に以下のようなスクリプトを作成しました。
# COMオブジェクトを作成する
Function Global:GetComObject($ProgID)
{
New-Object -ComObject $ProgID
}
# プロパティを呼び出す
Function Global:GetPropFromCom($obj, $PropertyName)
{
# $obj:COMオブジェクト
# $PropertyName:プロパティ名
# $Args:パラメータを必要とするプロパティ
If ( -Not ($obj -is [System.__ComObject]))
{ Throw "__ComObjectではありません"; Return }
# System.Typeを取得して、プロパティを呼び出す
$type = $obj.GetType()
$type.InvokeMember( $PropertyName,
[System.Reflection.BindingFlags]::GetProperty ,
$null, $obj, $args)
}
System.Typeのインスタンスを生成してプロパティをInvokeするというのがこのスクリプトです。これを使って以下のように実行すれば、問題なくインストール済みのソフトウェアの一覧を取得することができます。
PS (10) >$wi = GetComObject WindowsInstaller.Installer
PS (11) >$ps = GetPropFromCom $wi Products
PS (12) >ForEach ($i in $ps)
>> { GetPropFromCom $wi ProductInfo $i ProductName }
>>
Cardmod_x86 and MSITPintool
Microsoft ASP.NET Futures (May 2007)
Microsoft ASP.NET 2.0 AJAX Extensions 1.0
以下続く
Comments
Anonymous
October 01, 2007
PingBack from http://www.artofbam.com/wordpress/?p=4458Anonymous
October 02, 2007
The comment has been removedAnonymous
October 02, 2007
The comment has been removedAnonymous
October 04, 2007
エラーですAnonymous
January 16, 2008
PowerShell 2.0では、WMI関係の機能強化が行われています。どのような機能強化かと云えば、以下のようなものがあります。 Get-WmiObject:Impersonation(偽装)などのパラメータが追加された。