Skip to main content
評価してください: 

 

WMI の FAQ: トラブルシューティングとヒント

メモ:  このドキュメントは、当初「Windows Management Instrumentation : よく寄せられる質問」として発行されたものです。

*

トピック

手順 1Q 1. WMI はどのようなツールで、どのような機能を提供しますか。
スクリプトとはいったい何かQ 2. WMI はどのプラットフォームに対応していますか。
それでも、スクリプトの内容はコードのように見えるQ 3. WMI で特定の機能が公開されているかどうかを調べるにはどうすればよいですか。
スクリプトの実行Q 4. 使用したい機能が WMI で提供されていない場合はどうすればよいですか。
頭字語についてQ 5. WMI を使用しているサンプル スクリプトはどこにありますか
スクリプト センターのナビゲートQ 6. あるバージョンの Windows で実行できるスクリプトを他のバージョンの Windows で実行できないのですが、これはなぜですか。
独り立ちのときですQ 7. WMI スクリプトの実行時にエラーが返されるのですが、何が原因でしょうか。
初心者のためにQ 8. WMI が動作していません。どのようにトラブルシューティングすればよいですか。
手順 1Q 9. WMI 名前空間セキュリティを設定するにはどうすればよいですか。
スクリプトとはいったい何かQ 10. WMI でリモート コンピュータを管理するにはどうすればよいですか。
それでも、スクリプトの内容はコードのように見えるQ 11. リモート操作に 3 台目のコンピュータが関与している場合にリモート操作が失敗するのですが、何が原因でしょうか
スクリプトの実行Q 12. クエリが完了するまでに時間がかかるのですが、何が原因でしょうか。
頭字語についてQ 13. 特定のコンピュータにインストールされているすべてのアプリケーションの一覧を表示するにはどうすればよいですか。
スクリプト センターのナビゲートQ 14. パフォーマンス カウンタ データを取得するにはどうすればよいですか。

*

Q 1. WMI はどのようなツールで、どのような機能を提供しますか。

Windows Management Instrumentation (WMI) は、Windows 管理技術の中核を担っています。WMI は、ローカル コンピュータとリモート コンピュータの両方の管理に使用できます。WMI は、プログラミング言語やスクリプト言語で日常的な管理タスクを実行するための一貫したアプローチを提供します。たとえば、次のようなことが可能です。

  • リモート コンピュータ上のプロセスを起動できます。
  • 特定の日時にプロセスを実行するようにスケジュールを設定できます。
  • コンピュータをリモートで再起動できます。
  • ローカル コンピュータまたはリモート コンピュータにインストールされているアプリケーションのリストを取得できます。

ローカル コンピュータまたはリモート コンピュータ上の Windows イベント ログを照会できます。

WMI (Windows Management Instrumentation) の Instrumentation という単語は "計器" や "計器による測定" を意味します。ちょうど自動車の計器類がエンジンに関する情報を示すように、WMI はコンピュータ システムの内部状態に関する情報を示します。WMI では、Windows システム内に検出されたディスクやプロセスなどのオブジェクトをモデリングすることにより、"計器情報" を提供します。WMI によるシステム オブジェクトのモデリングには、Win32_LogicalDisk や Win32_Process などのクラスが使用されます。クラス名から推察できるように、Win32_LogicalDisk はコンピュータ上の論理ディスクをモデリングするクラス、Win32_Process はコンピュータ上で現在稼動している任意のプロセスをモデリングするクラスです。クラスは、Common Information Model (CIM) と呼ばれる拡張可能スキーマに基づいています。CIM スキーマは、Distributed Management Task Force ( http://www.dmtf.org) の公開規格です。

WMI には、上記のほか、イベント処理、リモート処理、クエリ処理、ビュー、スキーマのユーザー拡張、情報取得などの機能もあります。

Q 2. WMI はどのプラットフォームに対応していますか。

WMI は、最近のバージョンの Windows すべてに対応しています。Windows Me、Windows 2000、Windows XP、および Windows Server 2003 では WMI が標準でインストールされます。

Windows 98 および Windows NT 4.0 の場合は、 http://www.microsoft.com/japan/downloads から WMI をダウンロードしてインストールすることができます。ダウンロード名 "Windows Management Instrumentation (WMI) SDK 1.5 (Windows 95/98/NT 4.0)" を検索してください。

なお、Windows NT 4.0 に WMI をインストールして実行するには、事前に Service Pack 4 以降を適用しておく必要があります。

WMI を使用するには、さらに以下のソフトウェアが必要です。

  1. Microsoft® Internet Explorer 5.0 以降
  2. Windows スクリプト ホスト (WSH)。WSH は、Windows 2000、Windows XP、Windows Server 2003、および Windows Me に付属していますが、Windows NT4 と Windows 98 には付属していません。WSH は、 http://www.microsoft.com/japan/downloads からダウンロードできます。Windows XP および Windows Server 2003 には、最新バージョンの WSH 5.6 が付属しています。

Q 3. WMI で特定の機能が公開されているかどうかを調べるにはどうすればよいですか。

WMI とその機能に関する詳細なリファレンス情報をお探しなら、MSDN を参照することをぜひお勧めします。 http://msdn.microsoft.com/en-us/library/aa394572.aspx に用意されている『WMI Reference』(英語) をご覧ください。『WMI Reference』には、WMI の標準インストールに含まれているクラス、スクリプト オブジェクト、および API がほぼすべて網羅されています。なお、オペレーティング システムに付属していない WMI プロバイダによって作成されるクラスは、MSDN に情報が記載されていないことがありますが、Platform SDK に情報が記載されている場合もあります。

情報がどのようにカテゴリ分けされているかを理解しておくと、クラスを検索したり、必要な機能が用意されているかどうかを調べたりするときに役立ちます。特定のタスクを実行するために複数のクラスが必要になることもあります。たとえば、コンピュータの基本的なシステム情報を取得する場合を考えてみましょう。Win32_OperatingSystem クラスを使うと、使用可能メモリに関する情報を取得できますが、コンピュータ上の空きディスク容量に関する情報も併せて取得するには、別のクラス (Win32_LogicalDisk など) を使用する必要があります。WMI で何ができ、何ができないかについては、「あるバージョンの Windows で実行できるスクリプトを他のバージョンの Windows で実行できないのですが、これはなぜですか」の質問を参照してください。

Windows 2000 以降のプラットフォームでは、CIM Studio というツールを使って WMI クラスを参照できます。このツールに関する情報とこのツールのダウンロード ファイルについては、http://www.microsoft.com/japan にアクセスし、キーワード "WMI ツール" で検索してください。なお、CIM Studio は WMITools.exe によってインストールされるファイルの 1 つです。また、サポート外ですが、WMI と共に自動的にインストールされる Wbemtest.exe ユーティリティで WMI データを参照することも可能です。

Windows XP と Windows Server 2003 では、下記のスクリプトを使うと、クラス名に特定の文字列が含まれているクラスを検索できます。このスクリプトを使用するには、Search.vbs という名前のテキスト ファイルとして保存します。実行時に検索対象のキーワードを指定します。たとえば、クラス名に "service" が含まれているクラスを検索するには、コマンド プロンプトから次のコマンドを実行します。

cscript search.vbs service

' Script for finding a class in WMI Repository
 
Set args = wscript.arguments
If args.Count <= 0 Then
    Wscript.Echo "Tool to search for a matching class in the WMI Repository. " 
    Wscript.Echo "USAGE: <keywordToSearch> [<namespaceToSearchIn>]"
    Wscript.Echo "Example1: Cscript search.vbs service"
    Wscript.Echo "Example2: Cscript search.vbs video root\cimv2"
Else
    ' If no Namespace is specified then the Default is the ROOT namespace
    rootNamespace = "\\.\ROOT"
    keyword = args(0)
    If args.Count > 1 Then
        rootNamespace = args(1)
    End If    
    EnumNameSpace rootNamespace 
    Wscript.Echo vbNewLine
End if
  
' Subroutine to recurse through the namespaces
 
Sub EnumNameSpace(parentNamespaceName)
 
Set objService = GetObject("winmgmts:" & parentNamespaceName)
 
Set collMatchingClasses = objService.Execquery _
    ("Select * From meta_class Where __class " & _
    "Like '%" & keyword & "%'")
If (collMatchingClasses.count > 0) Then
    Wscript.Echo vbNewLine 
    Wscript.Echo vbNewLine
    Wscript.Echo "Matching Classes Under Namespace: " & parentNamespaceName
 
    For Each matchingClass in collMatchingClasses 
        Wscript.Echo "    " & matchingClass.Path_.CLASS
    Next    
End if
 
Set collSubNamespaces = objService.Execquery _
    ("select * from __namespace")
For Each subNameSpace in collSubNamespaces 
    EnumNameSpace subNameSpace.path_.namespace + _
        "\" + subNameSpace.Name
Next
 
End Sub

このスクリプトは、Windows XP および Server 2003 でのみ動作します。これは、WMI クエリ言語に含まれている LIKE 演算子は、この 2 つのプラットフォームでしか使用できないためです。

Q 4. 使用したい機能が WMI で提供されていない場合はどうすればよいですか。

実際にスクリプトを作成しているうち、目的のタスクを WMI では実行できなかったり、WMI では効率性に欠けるというようなケースに遭遇することが考えられます。このような場合は、最初にオペレーティング システムに用意されている他のスクリプト技術で目的の機能が提供されていないかどうかをチェックしてください。たとえば、ADSI (Active Directory サービス インターフェイス) を使えば Active Directory を管理でき、CDO (Collaboration データ オブジェクト) を使えばスクリプト内から電子メールを送信できます。Windows オペレーティング システムに適切なスクリプト インターフェイスがない場合は、目的の機能を実行できるサード パーティ ソフトウェアの使用を検討してください。

スクリプト インターフェイスがない場合は、目的の機能を提供する WMI プロバイダを作成することができます。ただし、WMI プロバイダはスクリプト言語では作成できず、C++ または C# で作成する必要があります。詳細については、従来型 WMI プロバイダの作成に関する指示が記載されている MSDN の「Using WMI」を参照してください。.NET Framework を使ってプロバイダを作成したい場合は、MSDN ライブラリから "WMI によるアプリケーションの管理" を検索してください。

WMI の機能を拡張するソフトウェアが多数のサード パーティから市場に出されています。サード パーティ ツールは、インターネットから検索できます。また、ニュースグループへの質問を通じて情報を得ることも考えられます。「WMI を使用しているサンプル スクリプトはどこにありますか」の質問を参照してください。

Q 5. WMI を使用しているサンプル スクリプトはどこにありますか

MSDN (Microsoft Developers Network) および TechNet は共にサンプルの宝庫です。この 2 つのサイト上の役立つページへのリンクを、次にいくつか示します。

TechNet スクリプト センター
技術および管理タスク別に分類された数百種類のサンプルがあります。
http://www.microsoft.com/japan/technet/scriptcenter/default.mspx.  
MSDN
http://msdn.microsoft.com/library/default.aspx
WMI スクリプトについては、"WMI System Administration scripts" を検索してください。
WMIC (WMI コマンド ライン ユーティリティ) については、 http://msdn.microsoft.com/en-us/library/aa394531.aspx (英語) を参照してください。
WMI Software Developers Kit (SDK)
カテゴリ別の問題解決方法については、「Using WMI」から「WMI Tasks for Scripts and Applications」を参照してください。 http://www.microsoft.com/downloads/details.aspx?FamilyId=A55B6B43-E24F-4EA3-A93E-40C0EC4F68E5&displaylang=en
Windows 2000 Scripting Guide オンライン (英語)
完全版のオンライン ガイドです。WMI サンプル スクリプトが豊富に用意されています。
http://www.microsoft.com/technet/scriptcenter/guide/default.mspx 
TechNet 上の「Tales from the Script」コラム
初級および中級向けのスクリプト トピック。
http://www.microsoft.com/japan/technet/community/columns/scripts/default.mspx 
MSDN の「SCRIPTING CLINIC」コラム
上級者用スクリプト トピック
http://www.microsoft.com/japan/msdn/columns/default.aspx
ページのトップへページのトップへ

Q 6. あるバージョンの Windows で実行できるスクリプトを他のバージョンの Windows で実行できないのですが、これはなぜですか。

主な原因として、新しいバージョンの Windows に用意されているクラス、プロパティ、およびメソッドが以前のバージョンの Windows では使用できないことが考えられます。使用できるかどうかを確認するには、MSDN ライブラリ ( http://msdn.microsoft.com/library/default.aspx) WMI Software Developer Kit (SDK) の各クラスに関する「Requirements」の項をチェックしてください。たとえば、Win32_PingStatus クラスの必要条件には、オペレーティング システムが Windows XP または Windows Server 2003 であることが含まれています。このため、スクリプトから Windows 2000 上の Win32_PingStatus クラスにアクセスしようとすると、スクリプトの実行に失敗し "クラスが見つかりません" のエラーが返されます。

同様に、SNMP プロバイダなどの WMI データ プロバイダには、特定のオペレーティング システムにしか対応していないものや、WMI の既定インストールに含まれていないものがあります。SDK では、トピック内でこれらのプロバイダに言及するとき、「About WMI」のトピック「Operating System Availability」へのリンクがメモ欄に示されています。

標準 WMI プロバイダの一覧については、「WMI Reference」の「WMI Providers」を参照してください。

一般に、新しいバージョンの Windows に新しいプロバイダが追加されても、そのプロバイダの機能が以前のバージョンの Windows で使用できるようになることはありません。たとえば、Ping プロバイダで定義されている Win32_PingStatus クラスを Windows 2000 でも使用できるようになる見込みはありません。プロバイダが新しいバージョンの Windows の機能を利用する場合、その機能が以前のバージョンに用意されていなければ、このような結果になります。

この他に、同じバージョンの Windows を 2 台のコンピュータで使用していても、一方では実行できるスクリプトをもう一方では実行できない場合もありますが、これは何らかの問題が生じていることを意味します。このような問題のトラブルシューティングについては、「WMI スクリプトの実行時にエラーが返されるのですが、何が原因でしょうか」を参照してください。

Q 7. WMI スクリプトの実行時にエラーが返されるのですが、何が原因でしょうか。

最初に、そのエラーが本当に WMI エラーかどうかを確かめてください。WMI のエラー番号は 8004xxxx で始まります (例 : 80041001)。WMI エラー番号と戻りコードについては、 http://msdn.microsoft.com/library/default.aspx にアクセスし、「WMI Return Codes」を参照してください。必要な情報が見つからない場合は、MSDN でエラー番号を検索してみてください。

スクリプトの実行時にエラー番号が表示されなかった場合は、%windir%\system32\wbem\logs フォルダ内の WMI ログ ファイルを開くと、エラー番号を見つけることができます。実行したスクリプトが原因で発生したエラーがどれかを判断しにくい場合は、ログ全体を削除し、スクリプトを再度実行します。こうすると、スクリプトに関連するエラーを特定しやすくなります。

ログ ファイルを調べてもエラーが見つからない場合は、ログ ファイルのログ レベルを必要に応じて再設定します。情報の詳細度を最も高くするには、ログ レベルを詳細モードに設定します。Windows 2000、Windows NT、および Windows Me/98/95 ではログ レベル変更後に WMI を再起動する必要がありますが、Windows XP および Windows Server 2003 ではその必要はありません。ログ レベルの構成の詳細については、 http://msdn.microsoft.com/library/default.aspx にアクセスし、「Logging WMI Activity」を検索してください。

Windows イベント ログにエラーが記録されることもあります。ソースが Winmgmt になっているイベントを探してください。

Windows XP または Windows Server 2003 では MSFT_WMIProvider クラスを使うと、プロバイダのロードとアンロード、クエリへの応答、メソッドの実行などのプロバイダ操作をトラブルシューティングできます。たとえば、プロバイダがクエリへの応答をキャンセルする直前に MSFT_WmiProvider_CancelQuery_Pre クラスのインスタンスが WMI から生成されます。さらに、キャンセル後には MSFT_WmiProvider_CancelQuery_Post クラスのインスタンスが生成されます。特定のスクリプトのクエリ操作が失敗する場合は、これらのイベント クラスが生成されるまで待機する監視用スクリプトを作成することで対処できます。これらのイベント クラスを監視用スクリプトが受信したときに、関係しているプロバイダとその種類、処理中のクエリ、および関連している名前空間を判別することができます。

詳細については、 http://msdn.microsoft.com/library/default.aspx にアクセスし、「Troubleshooting Classes」を検索してください。

下記のサンプル スクリプトでは、Ping プロバイダに関する問題をトラブルシューティングします。このスクリプトは、Ping 実行中に発生したすべてのイベント (プロバイダのロード、クエリの受信、エラーの発生など) を報告します。この情報に基づいて、プロバイダに問題があるのか、WMI サービスに問題があるのかを判断することができます。出力された情報のうち、ResultCode が 0 以外のイベントを探してください。一般に、0 以外のエラー コードは操作の失敗を示します。

下記のコードを .VBS ファイルに保存して、スクリプトを実行します。

Option Explicit
 
Sub Sink_OnObjectReady(oInst, oCtx)
    instcount = instCount+1
    Wscript.echo "Event " & cstr(instCount) & vbTab & _
        oInst.GetObjectText_ & vbNewLine        
End Sub
 
Sub Sink_OnCompleted(Hresult, oErr, oCtx)    
End Sub
 
'msftTroubleShooting.vbs starts here
 
DIM oLctr, oSvc, OSink, instCount, SrvName, SrvUserName, SrvPswd, args, argcount 
 
Set args = wscript.arguments
 
SrvName = "."
SrvUserName = Null
SrvPswd = Null
instcount = 0
 
argcount = args.Count
 
If (argcount > 0)  Then
    If args(0) = "/?" or args(0) = "?"   Then
        Wscript.Echo "Usage:        cscript msftTroubleShooting.vbs " _
            [ServerName=Null|?] [UserName=Null] [Password=Null]"
        Wscript.Echo "Example:    cscript msftTroubleShooting.vbs "
        Wscript.Echo "Example:    cscript msftTroubleShooting.vbs computerABC"
        Wscript.Echo "Example:    cscript msftTroubleShooting.vbs "
        Wscript.Echo "computerABC admin adminPswd"
        Wscript.Quit 1
    End If 
End If
 
Set oLctr = createObject("WbemScripting.Swbemlocator")
 
On Error Resume Next
If argcount = 0 Then
    Set oSvc = oLctr.ConnectServer(,"root\cimv2") 
    SrvName = " Local Computer "
Else
    srvname = args(0)
    If argcount >= 2 Then 
        SrvUserName = args(1)
    End If
    If argcount >= 3 Then 
        SrvPswd = args(2)
    End If
    Set oSvc = oLctr.ConnectServer(srvname,"root\cimv2",SrvUserName,SrvPswd)
End If
 
If Err = 0 Tthen
    Wscript.Echo "Connection to " & srvname & " is thru"  & vbNewLine
Else
    Wscript.Echo "The Error is " & err.description & _
        " and the Error number is " & err.number
    Wscript.Quit 1
End If
 
On Error Goto 0
 
Set oSink = WScript.CreateObject("WbemScripting.SWbemSink","Sink_")
oSvc.ExecNotificationQueryAsync oSink, _
    "Select * From MSFT_WmiProvider_OperationEvent Where " & _
        "provider = 'WMIPingProvider'"
 
Wscript.Echo "To stop the script press ctrl + C" & vbNewLine
Wscript.Echo "Waiting for events......"  & vbNewLine
 
While True
    Wscript.Sleep 10000     
Wend

Q 8. WMI が動作していません。どのようにトラブルシューティングすればよいですか。

スクリプトの実行時、CIM Studio などの WMI ベースのツールの実行時、または WMI コントロールの使用時には、WMI サービスに関する問題が発生することがあります。スクリプトが実行されなかったり、"アクセスは拒否されました" というエラー メッセージが表示されたりすることがあります。このエラーの原因としては、WMI が動作していないか、名前空間が正しく構成されていないかのどちらかが考えられます。また、クラスを提供している WMI プロバイダがロードされていない場合や、WMI リポジトリ (クラス定義の格納場所) が壊れた場合にも、エラーが発生することがあります。

WMI サービスに関する問題をトラブルシューティングするには、次の作業を行います。

  1. リモート コンピュータへの接続に関して問題が生じている場合は、ローカル コンピュータ上でスクリプトを実行してみてください。
  2. WMI サービスを再起動します。
  3. WMI リポジトリを再構築します。
  4. すべての WMI コンポーネントを再登録します。
  5. オペレーティング システムを再インストールします。
  6. マイクロソフト製品サポート サービスに問い合わせます。

リモート コンピュータへの接続に関して問題が生じている場合は、ローカル コンピュータ上でスクリプトを実行してみる

リモート コンピュータへの接続に関して問題が生じている場合は、他の操作を行う前にローカル コンピュータ上でスクリプトを実行してみてください。ローカル コンピュータ上でスクリプトを実行できるのであれば、「WMI でリモート コンピュータを管理するにはどうすればよいですか」のトピックを参照してください。ローカル コンピュータでスクリプトを実行できない場合は、次のトラブルシューティング手順を実行してください。

ローカル コンピュータ上での WMI 操作が失敗し、予期せぬエラー コードが返される場合や、WMI コントロールを起動できない場合は、ローカル WMI サービスが稼動しているかどうかを確認します。下記のコードを .VBS ファイルに保存して、コマンド プロンプトからスクリプトを実行します。

Set Svc = GetObject ("winmgmts:root\default")

スクリプトを実行できるのであれば、WMI サービスは稼動しており、WMI サービス自体に問題はないと考えることができます。

スクリプトが失敗した場合は、スクリプト内で指定されている名前空間が正しい名前空間かどうかを確認します。サンプル スクリプトでは、root\default 名前空間への接続を試行します。この名前空間が存在しない場合は、多くの場合、WBEM_E_INVALID_NAMESPACE (0x8004100E) エラーが返されます。

名前空間が存在していても、接続先のクラスが存在していないとスクリプトの実行が失敗します。その場合は、そのクラスにアクセスしようとした時点で次のいずれかのエラー コードが返される可能性があります。

  • WBEM_E_NOT_FOUND ( 0x80041002)
  • WBEM_E_OUT_OF_MEMORY (0x80041006)

クラスへの接続失敗は、WMI リポジトリが壊れていることが原因の場合もあります。その場合は、次のいずれかのエラー コードが返される可能性があります。

  • WBEM_E_INITIALIZATION_FAILURE ( 0x80041014 )
  • WBEM_E_CRITICAL_ERROR ( 0x8004100a )
  • WBEM_E_FAILED ( 0x80041001)

リポジトリが壊れていると思われる場合は、リポジトリを再構築するのが最善策となります。

WMI サービスを再起動する

WMI サービス (winmgmt) は常時稼動しているのが普通です。このサービスはコンピュータの起動時に稼動を開始し、コンピュータがシャットダウンされない限り停止されません。このサービスが何らかの原因で停止してしまった場合は、コマンド プロンプトから「net start winmgmt」と入力すると再起動することができます。さらに、WMI ベースのツール (Wbemtest など) やスクリプトで WMI 名前空間に接続したときには、WMI サービスが必ず自動的に再起動されるようになっています。WMI サービスが停止しているときに WMI を使用するスクリプトを実行すると、通常は、WMI サービスが自動的に再起動されます。

WMI サービスに関する問題が発生している場合は、サービスを手動で停止および再起動しなければならなくなることがあります。手順は次のとおりです。

  1. 最初に、問題の診断に役立つ追加情報が WMI エラー ログに記録されるように WMI の詳細ログ オプションを有効にします。詳細ログを有効にするには、次のレジストリ値を構成します。
    1. HKLM\Software\Microsoft\WBEM\CIMOM\Logging を 2 に設定します。
    2. HKLM\Software\Microsoft\WBEM\CIMOM\Logging file Max Size を 4000000 に設定します。
  2. WMI サービスを停止します。前述したように、WMI サービスの名前は "winmgmt" です。WMI サービスを停止するには、次のコマンドを実行します。
    winmgmt /kill
    Windows XP または Windows Server 2003 を使用している場合は、Svchost という名前のプロセスの中で WMI サービスが実行されます。このプロセスには、同じアカウントで実行されている他のサービスも含まれます。さらに、1 つのコンピュータ上で複数のインスタンスの Svchost が実行されることがよくあります。Svchost 全体を停止するのではなく、winmgmt /kill コマンドまたは net stop winmgmt コマンドを使って WMI サービスだけを停止してください。
  3. 手順 2 が成功した場合は、この手順をスキップして手順 4 に進みます。手順 2 で winmgmt サービスを停止できなかった場合は、コンピュータを再起動してから手順 4 に進みます。
  4. スクリプトを再度実行します。スクリプトが失敗した場合は、WMI リポジトリを必要に応じて再構築します。

リポジトリを再構築する

WMI リポジトリは %systemDrive%\%windir%\system32\wbem\Repository フォルダにあり、WMI プロバイダによって作成されたクラス定義の一元的な保存場所となります。リポジトリの破損が疑われる場合は、リポジトリを再構築することができます。ただし、リポジトリを再構築すると、WMI (またはオペレーティング システム) をインストールした後で追加された WMI 情報がリポジトリから失われる可能性があります。その場合は、リポジトリ内の元の位置に情報が格納されるように、対応するアプリケーションを手動で実行して情報を復元する必要が生じます。リポジトリを再構築するには、次の操作を行います。

  1. WMI サービスを停止します。
  2. コマンド プロンプトから次のコマンドを実行します。
    cd /d %windir%\system32\wbem
    rename Repository Rep_bak
  3. 上記のコマンドでは、WMI リポジトリが格納されているファイルの名前を変更しています。ファイル名を変更すると、オペレーティング システム上にリポジトリが存在しなくなります。リポジトリが存在しなければ、次回 WMI にアクセスしたときに Windows によってリポジトリが再作成されます。自動回復メカニズムが正しく動作しない場合は、リポジトリを手動で再構築することで対処できます。

    WMI の自動回復メカニズムでリポジトリを再構築するには、次の操作を実行します。
    • スクリプトを実行するか、または Wbemtest.exe などの WMI ベースのツールを使用して Root\Default への WMI 接続を確立します。接続を確立できれば、リポジトリは再構築されています。接続できない場合は、リポジトリを手動で再構築してみてください。

    WMI リポジトリを手動で再構築するには、次の手順を実行します。

    • リポジトリを手動で再構築するには、最初に、リポジトリ内の情報を再コンパイルするバッチ ファイルを作成します。レジストリ キー HKLM\Software\Microsoft\WBEM\CIMOM\Autorecover MOFs には、WMI (またはオペレーティング システム) のインストール時にコンパイルされたすべてのマネージ オブジェクト形式のファイル (MOF ファイル) のリストが含まれています。リポジトリを再構築するには、このレジストリ値に示されているファイル名を新しいバッチ ファイルにコピーします。このバッチ ファイルには WMI_Recover.bat という名前を付け、.MOF ファイル拡張子と .MFL ファイル拡張子が付いたファイルの両方を必ず含めてください。なお、MFL ファイルには、クラス、プロパティ、およびメソッドの説明のローカライズ版が格納されます。
      メモ帳で次のような行をバッチ ファイル内に記述します。

    C:\WINDOWS\system32\WBEM\cimwin32.mof
    C:\WINDOWS\system32\WBEM\cimwin32.mfl
    C:\WINDOWS\system32\WBEM\system.mof
    C:\WINDOWS\system32\WBEM\wmipcima.mof
    C:\WINDOWS\system32\WBEM\wmipcima.mfl

    • バッチ ファイルの各行の先頭に Mofcomp コマンドを追加します。Mofcomp.exe は、MOF ファイルをコンパイルするためのオペレーティング システム ユーティリティです。これにより、これらのファイルの情報が WMI リポジトリに追加されます。完成したバッチ ファイルの内容は、たとえば次のようになります。

    Mofcomp C:\WINDOWS\system32\WBEM\cimwin32.mof
    Mofcomp C:\WINDOWS\system32\WBEM\cimwin32.mfl
    Mofcomp C:\WINDOWS\system32\WBEM\system.mof
    Mofcomp C:\WINDOWS\system32\WBEM\wmipcima.mof
    Mofcomp C:\WINDOWS\system32\WBEM\wmipcima.mfl

    • バッチ ファイルを実行します。
    • また、次のコマンドを使うと、すべての MOF ファイルおよび MFL ファイルをコンパイルすることができます。
      cd /d %windir%\system32\wbem
      for %i in (*.mof,*.mfl) do Mofcomp %i
    • 完了したら、\Logs\Mofcomp.log をチェックし、コンパイル エラーがないことを確認します。
  4. スクリプトを再度実行します。

WMI コンポーネントを再登録する

root\default に接続できない場合は、WMI コンポーネントが正しく登録されていない可能性があります。WMI で使用する .DLL ファイルと .EXE ファイルは %windir%\system32\wbem に置かれます。このディレクトリに格納されているすべての .DLL ファイルと .EXE ファイルの再登録が必要になることがあります。また、64 ビット システムを使用している場合は、%windir%\sysWOW64\wbem 内の .DLL ファイルと .EXE ファイルについても再登録が必要になることがあります。

  1. WMI コンポーネントを再登録するには、コマンド プロンプトから次のコマンドを実行します。
    cd /d %windir%\system32\wbem
    for %i in (*.dll) do RegSvr32 -s %i
    for %i in (*.exe) do %i /RegServer
  2. スクリプトを再度実行します。

オペレーティング システムを再インストールする

この段階でまだ root\default に接続できない場合は、オペレーティング システムを再インストールする必要があります。Windows を再インストールしてから、スクリプトをもう一度実行してみてください。

マイクロソフト製品サポートサービスに問い合わせる

WMI がどうしても動作しない場合は、マイクロソフト製品サポート サービス (PSS) に問い合わせる必要があります。詳細については、 http://support.microsoft.com/default.aspx を参照してください。

Q 9. WMI 名前空間セキュリティを設定するにはどうすればよいですか。

WMI コントロールを使って名前空間セキュリティを設定する

名前空間セキュリティは、WMI コントロールを通じて管理できます。WMI コントロールを起動するには、コマンド プロンプトに次のコマンドを入力します。

wmimgmt

Windows 9x コンピュータまたは Windows NT4 コンピュータに WMI をインストールしている場合は、上記の代わりに次のコマンドを入力します。

wbemcntl.exe

また、次の方法で WMI コントロールの [セキュリティ] タブにアクセスすることもできます。

  1. [マイ コンピュータ] アイコンを右クリックし、[管理] をクリックします。
  2. [サービスとアプリケーション] をダブルクリックし、[WMI コントロール] をダブルクリックします。
  3. [WMI コントロール] を右クリックし、[プロパティ] をクリックします。
  4. [WMI コントロールのプロパティ] ダイアログ ボックスの [セキュリティ] タブをクリックします。
  5. プラス記号 (+) の付いた [Root] フォルダが表示されます。このツリーを展開し、アクセス許可を設定したい名前空間を探します。
  6. [セキュリティ] をクリックします。ユーザーとアクセス許可の一覧が表示されます。目的のユーザーが一覧に示されていれば、アクセス許可を適切に変更します。目的のユーザーが一覧に示されていない場合は、[追加] をクリックし、アカウントの所属先 (ローカル コンピュータやドメインなど) からユーザーを追加します。

メモ

  • 名前空間セキュリティを表示および設定するには、[セキュリティの読み取り] アクセス許可と [セキュリティの編集] アクセス許可が自分のアカウントに付与されている必要があります。管理者は、既定でこれらのアクセス許可が付与されており、必要に応じてこれらのアクセス許可を他のユーザーに割り当てることができます。
  • 目的のユーザーが名前空間にリモートにアクセスできるようにするには、[リモートの有効化] アクセス許可を選択する必要があります。
  • 既定では、名前空間に対して設定したユーザー アクセス許可はその名前空間に対してのみ適用されます。その名前空間のほかに、その下位にあるすべての名前空間へのアクセスをユーザーに許可したい場合や、下位の名前空間へのアクセスだけをユーザーに許可したい場合は、[詳細設定] をクリックします。[編集] をクリックし、表示されたダイアログ ボックスでアクセスの適用範囲を指定します。

Q 10. WMI でリモート コンピュータを管理するにはどうすればよいですか。

一般に、WMI でローカル コンピュータに対して実行できる操作は、ローカル管理者特権でアクセスできるリモート コンピュータに対しても実行可能です。リモート名前空間へのアクセス権を持っているユーザー (「WMI 名前空間セキュリティを設定するにはどうすればよいですか」参照) は、リモート管理が有効になっているリモート コンピュータに接続して、自分にアクセス許可が与えられている任意の操作を実行することができます。さらに、リモート コンピュータで委任が有効になっていれば、委任を行うこともできます。委任を行うと、リモート コンピュータでクライアントによって提供された資格情報を使用して、さらに別のコンピュータから情報を取得することが可能です。つまり、コンピュータ A でスクリプトを実行してコンピュータ B に接続することができ、コンピュータ B ではコンピュータ A 上のスクリプトから渡されたユーザー名とパスワードを使用してコンピュータ C に接続することができます。委任のシナリオについては、「リモート操作に 3 台目のコンピュータが関与している場合にリモート操作が失敗するのですが、何が原因でしょうか」のトピックを参照してください。

WMI ツールを使ってリモート名前空間に接続するには

  1. CIM Studio や Wbemtest などのツールを使用してリモート名前空間に接続する場合は、"\\<machinename>\root\<namespace>" の形式で名前空間を指定する必要があります。
    例 : \\myserver\root\cimv2
  2. 認証は、Kerberos か NTLM のどちらかによって処理されます。NTLM 認証または既定の認証 (非 Kerberos 認証) を使用するには、次の指定を行います。
    [ユーザー] : <ドメイン名>\<ユーザー名>
    [パスワード] : <パスワード>
    [機関] : 空白のままにしておくか、「NTLMDomain:<ドメイン名>」と入力します。[機関] パラメータを含める場合は、[ユーザー] パラメータの指定から "<ドメイン名>\" を省略しユーザー名だけを入力します。次に、例を示します。

    [ユーザー] : kenmyer
    [パスワード] : 45Tgfr98q
    [機関] : NTLMDomain:fabrikam
  3. Kerberos 認証を使用するには、次の指定を行います。
    [ユーザー] : <ドメイン名>\<ユーザー名>
    [パスワード] : <パスワード>

    [機関] : 「Kerberos:<ドメイン名>\<コンピュータ名>」と入力します。次に、例を示します。

    [ユーザー] : kenmyer
    [パスワード] : 45Tgfr98q
    [機関] : Kerberos:fabrikam\atl-ws-01

スクリプトを使ってリモート コンピュータ上の WMI に接続するには

  1. 最初に、リモート名前空間への適切なアクセス許可が自分のアカウントに付与されているかどうかを確認します。これらのアクセス許可があれば、ユーザー資格情報を指定せずにリモート コンピュータに接続することができます。ログオンに使用している資格情報が接続に使用されます。
  2. ユーザー資格情報を指定する必要がない場合は、"モニカ文字列" と呼ばれる短縮版の接続構文でリモート コンピュータに接続することができます。詳細については、 http://msdn.microsoft.com/library/default.aspx にアクセスし、「Constructing a Moniker String」を検索してください。たとえば、このモニカでリモート コンピュータ TargetComputer 上の既定名前空間に接続する場合では、次のように指定します。なお、ここでは名前空間を指定していないので、自動的に既定名前空間に接続されます。
    • Set objWMIService = GetObject("winmgmts:\\TargetComputer”)

    • ログオン先と異なるドメインに TargetComputer が含まれている場合は、モニカにドメイン名を含める必要があります。この場合、ドメイン名を含めないと、"アクセスは拒否されました" のエラーが返されます。たとえば、次のモニカでは、ドメイン DomainName 内のコンピュータ TargetComputer に接続します。

      Set objWMIService = GetObject("winmgmts:\\DomainName\TargetComputer”)

    • 必須ではありませんが、モニカ自体の中に WMI 名前空間を指定することもできます。複数の異なるプラットフォームを扱っている場合は、オペレーティング システムによって既定名前空間が異なる可能性があるので、WMI 名前空間を指定しておくことをお勧めします。たとえば、Windows 2000、Windows XP、および Windows Server 2003 では root\cimv2 が既定の名前空間となりますが、Windows NT 4.0 および Windows 98 では root\defaul が既定の名前空間となります。

      次のモニカでは、リモート コンピュータ TargetComputer 上の root\cimv2 名前空間に接続します。

      Set objWMIService = GetObject("winmgmts:\\TargetComputer\root\cimv2)

    • 複数のプラットフォームを扱う場合は、偽装レベルの指定も必要になることがあります。Windows 2000 およびそれ以降のバージョンの Windows では [偽装する] が既定の偽装レベルとなりますが、それ以前のバージョンの Windows では [識別する] が既定の偽装レベルとなります。Windows NT 4.0 コンピュータや Windows 98 コンピュータを扱っている場合は、モニカ文字列に偽装レベルを含める必要があります。さらに、委任を使用する場合も、偽装レベルを含める必要があります。

      次のモニカでは、コンピュータ TargetComputer 上の root\cimv2 名前空間に接続し、偽装レベルとして [偽装する] を指定しています。

      Set objWMIService = GetObject _
      ("winmgmts:{impersonationLevel=Impersonate}!\\TargetComputer\root\cimv2")

    • 最後に、接続先の OS および接続元の OS のバージョンに応じて認証レベルの設定が必要になることがあります。認証レベルを設定すると、接続中に使用する DCOM 認証およびプライバシーの種類を指定することができます。認証なしから、パケット単位の暗号化認証に至るまでの各設定があります。

      次のモニカでは、コンピュータ TargetComputer 上の root\cimv2 名前空間に接続し、偽装レベルとして [偽装する] を指定しています。さらに、認証レベルを pkt に設定しています。

      Set objWMIService = GetObject("winmgmts:" _
      & "{impersonationLevel=impersonate," _ &
      "authenticationLevel=pkt}!\\ _
      TargetComputer\root\cimv2")

  3. スクリプト内でユーザー資格情報を指定することもできます。これにより、管理特権を必要とするスクリプトを実行しながら、標準のユーザー アカウントでコンピュータにログオンしたりすることが可能になります。詳細については、 http://msdn.microsoft.com/library/default.aspx にアクセスし、「Creating a WMI Script」を検索してください。

    wbemImpersonationLevelImpersonate = 3
    wbemAuthenticationLevelPktPrivacy = 6
    Set objLocator = CreateObject("WbemScripting.SWbemLocator")
    Set objService = objLocator.ConnectServer _
    ("TargetComputer", "root\cimv2", "UserName", "Password")
    objService.Security_.ImpersonationLevel = wbemImpersonationLevelImpersonate
    objservices.Security_.AuthenticationLevel = wbemAuthenticationLevelPktPrivacy

メモ   一般に、管理者パスワードをスクリプト内にハードコーディングすることはお勧めできません。実行のたびに、スクリプトからパスワードを要求するプロンプトを表示するようにしてください。

詳細については、 http://msdn.microsoft.com/library/default.aspx にアクセスし、「Connecting Between Different Operating Systems」を検索してください。

WMIC を使って WMI に接続するには

リモート名前空間へのアクセス権があり、接続先のコンピュータでリモート処理が有効化されていれば、接続時にユーザー名とパスワードを指定する必要はありません。この場合は、WMIC が現在のユーザー資格情報を使用して自動的に接続を行います。次に、例を示します。

WMIC /NODE:"computer1" OS GET Caption,CSDVersion,CSName



委任を行う必要がある場合は、WMIC 接続文字列に /IMPLEVEL:Delegate と /AUTHORITY の設定を含めます。次に、例を示します。

WMIC /NODE:"computer1" /IMPLEVEL:Delegate /AUTHORITY:"Kerberos:domain\computer1" OS

上記の代わりに、WMIC 経由で接続するときに使用するユーザー アカウントとパスワードを明示的に指定することもできます。なお、WMI スクリプトの場合と同様、既定で WMI リモート接続特権が付与されるのは管理者だけです。次に、例を示します。

WMIC /NODE:"computer1" /USER:"domainname\username" OS GET Caption,CSDVersion

次のサンプル コマンドでは、ユーザー名と共にパスワードを指定しています。

WMIC /NODE:"computer1" /USER:"domainname\username" /PASSWORD:"userpassword" OS GET Caption,CSDVersion,CSName

リモート接続の詳細については、 http://msdn.microsoft.com/library/default.aspx にアクセスし、「Connecting to WMI on a Remote Computer」を検索してください。

"アクセスは拒否されました" エラーは何を意味するか

リモート WMI 名前空間またはリモート WMI オブジェクトに接続しようとしたときに "アクセスは拒否されました" エラーが表示されることがあります。"アクセスは拒否されました" エラーには、種類がいくつかあります。

0x80041003 (WBEM_E_ACCESS_DENIED)
このエラーは、主に、必要な WMI 特権が付与されていないプロセスが名前空間にアクセスしようとした場合に発生します。リモート アクセスを開始するアカウントは、ターゲット コンピュータ上の管理者になっている必要があります。さらに、アカウントに対して特定の特権が有効になっていることが必要になる場合もあります。
このエラーをトラブルシューティングするには、リモート名前空間上の名前空間セキュリティをチェックして、アカウントに対して有効になっている特権を確認します。

0x80070005 (DCOM ACCESS_DENIED)
このエラーは、リモート サーバーが接続ユーザーを認識しないか、または接続ユーザーに何らかの制限がかかっている (ユーザーがロックアウトされているなど) 場合に発生します。このエラーが最も発生しがちなのは、アカウントが異なるドメインに所属している場合です。また、次のように、WMI セキュリティに対して最近加えられた変更との関連でこのエラーが発生することもあります。

  • 以前のバージョンの Windows では空白のパスワードが許容されていましたが、Windows XP および Windows Server 2003 では空白のパスワードは許容されません。
  • WMI では、Windows 98 クライアントに対する非同期コールバックが許容されません。Windows 98 コンピュータから Windows XP コンピュータに SWbemServices.ExecNotificationQueryAsync などの呼び出しを行うと、Windows 98 コンピュータに "アクセスは拒否されました" エラーが返されます。
  • DCOM 構成アクセス設定が変更されていることがあります。
  • ターゲット コンピュータ上で Windows XP が稼動している場合は、レジストリ キー HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa の下層の Forceguest 値を設定して、Guest アカウントを強制的にオフにする (値をゼロにする) 必要があります。

0x800706xx (DCOM RPC error)

このエラーは、リモート コンピュータ上でファイアウォールが構成されている場合に発生しがちです。DCOM によるリモート管理が可能になるように、ファイアウォール上の適切なポートを開放する必要があります。

また、IP とホスト名のマッピングに関する問題がコンピュータに生じていることもあります。そのような問題の可能性をチェックするには、次のように接続文字列内でホスト名の代わりに IP アドレスを使用してみてください。

Set objWMIService = GetObject("winmgmts:\\192.168.1.1")

リモートエラーをトラブルシューティングするには

  1. ユーザーがリモート コンピュータへのアクセス権を持っているかどうかを確認します。コマンド プロンプトから次のコマンドを実行します。
    net user \\<remotecomputer>\\C$ /u:<domain\username> *
  2. リモート コンピュータ上で詳細ログ レベルを有効化し、スクリプトを再実行します。スクリプトを実行した後、リモート コンピュータ上のログ (%windir%\system32\wbem\Logs\) をチェックします。
  3. 監査イベントを有効にし、どのアカウントが失敗した接続に対応しているかを調べます。監査を有効にすると、次のようなイベントがイベント ログに示されます。

    種類 : 失敗の監査

    ソース : Security

    分類 : ログオン/ログオフ

    イベント ID : 529

    日付 : 2004/06/14

    時刻 : 10:52:35

    ユーザー : NT AUTHORITY\SYSTEM

    コンピュータ : <remote machine>

    説明 :

    ログオンの失敗 :

    原因 : ユーザー名が不明またはパスワードが無効です。

    ユーザー名 : xuser

    ドメイン : NTDEV

    ログオンの種類 : 3

    ログオン プロセス : NtLmSsp

    認証パッケージ : MICROSOFT_AUTHENTICATION_PACKAGE_V1_0

    ワークステーション名 : <console Machine gt;
  4. DCOM 構成に Access\Launch アクセス許可が含まれているかどうかをチェックします。スクリプトを実行するユーザーには、このアクセス許可が付与されている必要があります。
  5. 上記のチェックがいずれも OK であり、リモート コンピュータがユーザーを認識しているにもかかわらず、接続がまだ失敗し DCOM の <アクセスは拒否されました> エラーが返される場合は、次の情報を収集したうえで、マイクロソフト製品サポート サービス ( http://support.microsoft.com/default.aspx) にご連絡ください。
    • 各コンピュータで稼動しているオペレーティング システム
    • インストール履歴
    • 問題の再現手順
    • 実行に失敗するスクリプトまたはツール コード
    • WMI 接続に使用しているユーザー資格情報 (認証レベルと偽装レベルを含む)
    • 両方のコンピュータの %windir%\system32\wbem\logs を圧縮した zip ファイル

Q 11. リモート操作に 3 台目のコンピュータが関与している場合にリモート操作が失敗するのですが、何が原因でしょうか

クライアント コンピュータ (コンピュータ A) からリモート サーバー (コンピュータ B) を介して 3 台目のコンピュータ (コンピュータ C) にドメイン資格情報を転送する場合は、委任が必要になります。このように、特定の操作に対して複数のネットワーク ホップを行う必要があるときには委任が必要です。委任を行わないと、コンピュータ B がコンピュータ A から受信した資格情報を転送できず、その結果、コンピュータ C への接続が失敗します。

委任が必要になるシナリオを次に 2 つ示します。

  • WMI サーバー コンピュータからプリンタを列挙する場合。この場合、WMI は、プリンタ サーバーに接続されているリモート プリンタのプロパティを収集しようとしますが、この操作に委任が必要となります。クライアント コンピュータ A でスクリプトを実行し、プリント サーバー B に接続します。プリント サーバー B はこれを受けて、コンピュータ C に接続されているプリンタにアクセスしようとします。
  • WMI サーバーから NT 認証経由で SQL Server に接続する場合。この場合、WMI がサーバーから SQL Server に資格情報を転送できるように委任を行う必要があります。SQL Server で NT 認証ではなく SQL Server 標準認証 (SQL Server ベースのセキュリティ) が使用されているのであれば、SQL Server に接続するための接続文字列に委任は不要です。

上記のシナリオで委任を行うには、次の条件を満たす必要があります。

  • 3 つのコンピュータで稼動している Windows が Windows 2000、Windows XP、Windows Server 2003 のいずれかであること。Windows NT 4.0 または Windows 98 が稼動しているコンピュータでは委任を行うことができません。
  • コンピュータ B に対する委任を Active Directory 内で有効にすること。
  • WMI クライアント プロセス (コンピュータ A) から WMI サーバー (コンピュータ B) への接続では、認証プロトコルとして Kerberos を指定すること。認証プロトコルを指定するには、SWbemLocator.ConnectServer を呼び出す必要があります。このメソッドは、WMI スクリプト API ( http://msdn.microsoft.com/en-us/library/aa393258.aspx) (英語) に含まれています。

上記の手順を完了すると、コンピュータ B が委任対象として信頼されます。たとえば、コンピュータ B がコンピュータ C 上のリモート ファイル共有に要求を送信したとします。この場合、コンピュータ C 側では、転送された資格情報に基づいて、コンピュータ A 上のクライアント プロセスで指定されているユーザーを認証します。

委任は管理オプションの 1 つとして用意されていますが、コンピュータ A からコンピュータ B に資格情報が渡されることから、一般には委任の使用はお勧めできません。委任を受けたコンピュータ B では、他の用途に資格情報を使用することも可能になるため、セキュリティ上のリスクが生じます。

下記のスクリプトでは、Active Directory 内でコンピュータ アカウントに対して委任を有効にします。このスクリプトのテストは、ドメイン管理者アカウントを使用して Windows Server 2003 ドメイン内で行いました。このほか、テスト時の条件は次のとおりです。

  • Windows XP SP1 Professional が稼動しているコンピュータを WMI クライアント コンピュータ (コンピュータ A) として使用しました。
  • Windows Server 2003 が稼動しているコンピュータを WMI サーバー コンピュータ (コンピュータ B) として使用しました。
  • 3 台のコンピュータはいずれも同じ Active Directory ドメイン内に所属しています。委任では、対象となるすべてのコンピュータが同じドメイン内に所属していることが必要条件となります。
  • この例では、ファイル サーバー共有 (コンピュータ C) が WMI クライアントと同じ物理コンピュータ上に存在します。ただし、実際には、同じドメイン内であれば別のコンピュータに共有を置くことが可能です。
'Purpose:    Script to enable delegation on a computer and 
'then perform an operation that requires delegation

'Requirements:  The client computer must be a member of the same Active Directory 
'domain as the WMI Server specified in the argument to this script

'Permissions required:  The user that runs this script should be a member of 
'the Domain Administrators group in the Active Directory
 
Const UF_TRUSTED_FOR_DELEGATION  = &H80000
Set args  = Wscript.Arguments
 
' Terminate unless two arguments are specified when starting
'the script
If args.Count <> 2 then
    Wscript.Echo "You must provide a server name and delegation command line."
    Wscript.Echo "For example, start the script using syntax similar to this:"
    Wscript.Echo "cscript.exe this.vbs <WMI Server> <Delegation Command Line>"
    Wscript.Echo "cscript.exe this.vbs computer2 "
    Wscript.echo "\\computer1\c$\windows\system32\calc.exe"
    Wscript.Quit 1
end if
 
serverName = args(0)
argCommandLine = args(1)
 
' Connect locally and get the domain and DS_Computer object to 
' examine and/or modify
Set svc = GetObject("winmgmts:root\cimv2")
 
' Get some local machine variables to understand the environment we are working in

Set objEnum = svc.ExecQuery _
    ("Select domain, name From win32_computerSystem", "WQL", 48)
 
For Each obj in objEnum
    domain = obj.Domain
    computerName = obj.Name
Next
 
' Get the connection to the root\directory\ldap namespace to enable delegation
' on the remote computer from the local machine

Set svc = GetObject("Winmgmts:root\directory\ldap")
 
' Create the required context object

Set octx = CreateObject("wbemscripting.swbemnamedvalueset")
octx.Add "__PUT_EXT_PROPERTIES", Array("ds_userAccountControl")
octx.Add "__PUT_EXTENSIONS", true
octx.Add "__PUT_EXT_CLIENT_REQUEST", true
 
' Variable to determine whether or not we have modified the userAccountControl 
'and whether or not we have to modify it back when we are done

modified = False
 
Set objEnum = svc.ExecQuery _
    ("Select * From ds_computer Where ds_cn = '" & serverName & "'", "WQL", 48)
 
For Each obj in objEnum
 
' Store this variable to memory for restoration after this operation completes

    userAccountControlOriginal = obj.ds_userAccountControl
 
' Test to see if the computer is already trusted for delegation
    If CBool(userAccountControlOriginal And UF_TRUSTED_FOR_DELEGATION ) = False Then
 
        Wscript.Echo "Computer account not trusted for delegation yet"
                        
        ' Resume On Error while we try this initially
        On Error Resume Next
 
        ' Add this constant value to the value contained already
        obj.ds_userAccountControl = userAccountControlOriginal + _
            UF_TRUSTED_FOR_DELEGATION
 
        ' This should trust the computer account for delegation                
        obj.Put_ 1, octx
 
        If (Err.Number = 0) Then
        ' Set the flag so we know to modify it back to original setting
            modified = True             
        Else 
            Wscript.Echo Hex(Err.Number) & " " & _
                Err.Description
            Wscript.Quit 1
        End If
 
                On Error Goto 0:
 
    Else
    ' Already trusted for delegation so 
    ' continue with delegation code here
        Wscript.Echo "Computer account is trusted for delegation already"
 
    End If
 
    ' Get the locator object 
    Set lctr = CreateObject("WbemScripting.SWbemLocator")
 
    ' Get the service object from the remote server specifying the Kerberos authority
    Set delegationService = lctr.ConnectServer _
        (serverName, "root\cimv2", , , , _
            "kerberos:" & trim(domain) & "\" & Trim(serverName))
 
    ' Delegation level impersonation
    delegationService.Security_.ImpersonationLevel = 4 
 
    ' Get the object that will be used to test the delegation hop
    Set process = delegationService.Get("win32_process")
 
    ' Get the inparameter object for the method
    Set inparams = process.methods_("Create").inparameters
            
    ' Set the inparameter commandline value
    inparams.CommandLine = argCommandLine
 
    ' Execute the method
    Set oReturn = process.ExecMethod_("Create", inparams)
 
    ' Echo the output
    If (oReturn.ReturnValue = 0) Then
        Wscript.Echo oReturn.ProcessId & _
            " is the Process ID from the process " & _
                "creation using delegation"
    Else 
        Wscript.Echo "An error occurred, the return value for the " & _
            "Win32_Process.Create method is " & _
                oReturn.ReturnValue
    End If
 
    ' Set the value back to the original value
    If modified = True Then
            
        ' Subtract the added delegation privilege from the computer account       
        obj.ds_userAccountControl = _
            userAccountControlOriginal - UF_TRUSTED_FOR_DELEGATION
 
        ' Restore the original setting
        obj.put_ 1, octx
 
    End If                        
Next

上記のスクリプトは、2 つのメンバ コンピュータのどちらかで Windows NT 4.0 または Windows 98 が稼動している場合には動作しません。また、ターゲットが Windows NT 4.0 ファイル共有上に存在する場合にも、このスクリプトを実行できません。

手動でコンピュータを委任対象として信頼するには、次の操作を行います。

  1. [スタート] ボタンをクリックし、[すべてのプログラム] をクリックします。
  2. [管理ツール] をポイントし、[Active Directory ユーザーとコンピュータ] をクリックします。
  3. [Active Directory ユーザーとコンピュータ] で [Computers] ノードを展開し、委任対象として信頼するコンピュータを探します。
  4. そのコンピュータを右クリックし、[プロパティ] をクリックします。
  5. [コンピュータを委任に対して信頼する] をクリックし、[OK] をクリックします。

委任およびリモート接続の詳細については、「Connecting to a 3rd Computer-Delegation」( http://msdn.microsoft.com/en-us/library/aa389288.aspx) (英語) および「Securing a Remote WMI Connection」( http://msdn.microsoft.com/en-us/library/aa393266.aspx) (英語) を参照してください。

また、「WMI でリモート コンピュータを管理するにはどうすればよいですか」および「WMI 名前空間セキュリティを設定するにはどうすればよいですか」の質問も参照してください。

Q 12. クエリが完了するまでに時間がかかるのですが、何が原因でしょうか。

一般に、クエリが返すデータの量が多いと、クエリが完了するまでにかかる時間が長くなります。データのサブセットだけを取得できればよいのにクエリから要求するデータセットの規模が大きい場合は、返される情報を制限することで処理を高速化できることがよくあります。WQL (WMI Query Language) では、返されるプロパティ (フィールド) にもインスタンス (レコード) のセットにもフィルタをかけることができます。その例については、 http://msdn.microsoft.com/library/default.aspx (英語) にアクセスし、「Querying with WQL」を検索してください。また、「SELECT Statement for Data Queries」のトピックも参照してください。

プロバイダによっては、特定のプロパティに基づいてフィルタをかけることを前提として最適化が行われていることがあります。その場合は、WHERE 句の中で適切なフィルタ条件を指定すると、データ空間全体が列挙された後で WMI がコレクションにフィルタをかけるのではなく、プロバイダがアクティブに結果セットにフィルタをかけることができるようになり、パフォーマンスが向上することがあります。このように最適化されたプロパティの例としては、CIM_DataFile の Drive プロパティと Path プロパティがあります。

既定では、コレクションを複数回、両方向に走査することが可能な列挙体が WMI クエリから返されます。これにより、コレクション内のすべての項目をループした後、必要に応じてすべての項目を繰り返しループすることなどが可能です。返されるデータ セットが大きい場合は、この種類の列挙体によるメモリ消費が大きくなるため、パフォーマンスが低下することがあります。この問題は、クエリの実行時に WBEM_FLAG_FORWARD_ONLY フラグを設定することで回避できます。この種類の列挙体を使用してコレクションを 1 回だけループすることも可能ですが、各オブジェクトに使用しているメモリは使用後に解放されるので、パフォーマンスは低下しません。詳細については、「Semisynchronous Call with VBScript」( http://msdn.microsoft.com/en-us/library/aa392301.aspx) (英語) を参照してください。

ほとんどの場合、半同期クエリのパフォーマンスは非同期クエリと同等ですが、クエリの規模が大きい場合は、アプリケーションのメイン スレッドがクエリによって占有されたり、システムの過負荷を避けるために WMI がクエリを抑制したりすることがあります。このような場合は、クエリを非同期にするとパフォーマンスを向上できます。ただし、ほとんどのオペレーティング システムでは、非同期呼び出しはセキュリティが低くなるので注意が必要です。詳細については、「Asynchronous Query」( http://msdn.microsoft.com/en-us/library/aa391396.aspx) (英語) および「Setting Security on an Asynchronous Call」( http://msdn.microsoft.com/en-us/library/aa393614.aspx) (英語) を参照してください。

Q 13. 特定のコンピュータにインストールされているすべてのアプリケーションの一覧を表示するにはどうすればよいですか。

WMI には、Windows インストーラによってインストールされたアプリケーションを表す Win32_Product クラスがあります。ただし、[プログラムの追加と削除] に表示されるアプリケーションでも、この WMI クラスによるリストに含まれないものがあります。この問題を解決する方法の 1 つとして、レジストリからインストール済みアプリケーションのデータを収集することができます。ただし、インストール時にレジストリへの書き込みを行わないアプリケーションもあります。このトピックでは、スクリプトを使ってレジストリから情報を直接読み出す方法と、MOF ファイルとスクリプトを使って WMI から情報を取得する方法の 2 つを示します。

  1. 次のスクリプトでは、コンピュータにインストールされているアプリケーションの一覧を表示します。このスクリプトでは、WMI システム レジストリ プロバイダを使ってレジストリから情報を直接収集します。

    strHost = "."
    Const HKLM = &H80000002
    Set objReg = GetObject("winmgmts://" & strHost & _
    "/root/default:StdRegProv")
    Const strBaseKey = _
    "Software\Microsoft\Windows\CurrentVersion\Uninstall\"
    objReg.EnumKey HKLM, strBaseKey, arrSubKeys

    For Each strSubKey In arrSubKeys
    intRet = objReg.GetStringValue(HKLM, strBaseKey & strSubKey, _
    "DisplayName", strValue)
    If intRet <> 0 Then
    intRet = objReg.GetStringValue(HKLM, strBaseKey & strSubKey, _
    "QuietDisplayName", strValue)
    End If
    If (strValue <> "") and (intRet = 0) Then
    WScript.Echo strValue
    End If
    Next

  2. もう 1 つの方法として、MOF ファイルとスクリプトを使用する例を下に示します。この方法では、レジストリに自己登録しているインストール済みアプリケーションをすべて取得します。この MOF ファイルを使用するには、以下の手順に従ってください。

    手順 1 : 次の MOF 構文をコピーしてメモ帳に貼り付け、.MOF ファイルとして保存します (products.mof など)。

    qualifier dynamic:ToInstance;
    qualifier ProviderClsid:ToInstance;
    qualifier ClassContext:ToInstance;
    qualifier propertycontext:ToInstance;

    [dynamic, provider("RegProv"),
    ProviderClsid("{fe9af5c0-d3b6-11ce-a5b6-00aa00680c3f}"),
    ClassContext
    ("local|HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall")
    ]
    class Products {
    [key] string KeyName;
    [read, propertycontext("DisplayName")] string DisplayName;
    [read, propertycontext("DisplayVersion")] string DisplayVersion;
    [read, propertycontext("InstallLocation")] string InstallLocation;
    };


    手順 2 :コマンド プロンプトに「mofcomp products.mof」と入力します。これにより、MOF ファイルが WMI リポジトリに格納されます。

    手順 3 : リポジトリに格納した MOF と共に次のスクリプトを使ってデータにアクセスします。

    strComputer = "."
    Set WMI = GetObject("winmgmts:\\" & strComputer & _
    "\root\default")
    Set colItems = WMI.ExecQuery("Select * from Products")
    For Each objItem In colItems
    WScript.Echo "DisplayName: " & objItem.DisplayName
    WScript.Echo "DisplayVersion: " & objItem.DisplayVersion
    WScript.Echo "InstallLocation: " & objItem.InstallLocation
    WScript.Echo "KeyName: " & objItem.KeyName
    Next

Q 14. パフォーマンス カウンタ データを取得するにはどうすればよいですか。

Windows XP では、WMI を通じてパフォーマンス データをすばやく簡単に取得できる "Cooked Counter プロバイダ" が初めてサポートされるようになりました。Windows 2000 でもパフォーマンス データを取得することが可能ですが、"加工" されていないデータが表示されるので、ほとんどのカウンタの場合、有用な値が得られるようにデータの書式を整える必要が生じます。これに対し、Windows XP および Windows Server 2003 のパフォーマンス データは、Win32_PerfFormattedData クラスから直接取得できます。

Windows 2000 では Cooked Counter プロバイダを使用できないので、有意なパフォーマンス情報を得るには "未加工" のデータに対して計算を行う必要があります。

各種カウンタの正しい計算式を見つけるには、最初に WMI SDK (「Performance Counter Classes」のトピック) を参照するか、または目的のプロパティの "countertype" プロパティを調べて、目的のプロパティの数値カウンタ タイプを特定する必要があります。そのカウンタ タイプの計算式を「WMI Performance Counter Types」( http://msdn.microsoft.com/en-us/library/aa394569.aspx) (英語) から探してください。

Windows 2000 より前のシステムで WMI を使ってパフォーマンス カウンタを取得するには、パフォーマンス モニタ プロバイダを使用する必要があります。「Monitoring Performance With the Performance Monitoring Provider」( http://msdn.microsoft.com/en-us/library/aa392398.aspx) (英語) を参照してください。