次の方法で共有


診断のための Windows Management Instrumentation の使用

Windows Communication Foundation (WCF) は、WCF Windows Management Instrumentation (WMI) プロバイダーを通じて、実行時にサービスの検査データを公開します。

WMI の有効化

WMI は、Microsoft の Web-Based Enterprise Management (WBEM) 標準の実装です。 WMI SDK の詳細については、「 Windows Management Instrumentation」を参照してください。 WBEM は、アプリケーションが管理インストルメンテーションを外部管理ツールに公開する方法の業界標準です。

WMI プロバイダーは、WBEM 互換インターフェイスを介して実行時にインストルメンテーションを公開するコンポーネントです。 これは、属性と値のペアを持つ一連の WMI オブジェクトで構成されます。 ペアには、いくつかの単純なタイプがあります。 管理ツールは、実行時にインターフェイスを介してサービスに接続できます。 WCF は、アドレス、バインディング、動作、リスナーなどのサービスの属性を公開します。

組み込みの WMI プロバイダーは、アプリケーションの構成ファイルでアクティブ化できます。 これは、次のサンプル構成に示すように、<system.serviceModel> セクションの <diagnostics>wmiProviderEnabled 属性を使用して行われます。

<system.serviceModel>  
    …  
    <diagnostics wmiProviderEnabled="true" />  
    …  
</system.serviceModel>  

この構成エントリは、WMI インターフェイスを公開します。 管理アプリケーションは、このインターフェイスを介して接続し、アプリケーションの管理インストルメンテーションにアクセスできるようになりました。

WMI データへのアクセス

WMI データには、さまざまな方法でアクセスできます。 Microsoft では、スクリプト、Visual Basic アプリケーション、C++ アプリケーション、および .NET Framework 用の WMI API を提供しています。 詳細については、「WMIの使用」を参照してください。

注意事項

.NET Framework に用意されているメソッドを使用して WMI データにプログラムでアクセスする場合は、接続が確立されたときにこのようなメソッドが例外をスローする可能性があることに注意してください。 接続は、 ManagementObject インスタンスの構築中ではなく、実際のデータ交換を含む最初の要求で確立されます。 したがって、 try..catch ブロックを使用して、考えられる例外をキャッチする必要があります。

WMI では、トレースとメッセージのログ記録レベル、および System.ServiceModel トレース ソースのメッセージ ログ記録オプションを変更できます。 これを行うには、LogMessagesAtServiceLevelLogMessagesAtTransportLevelLogMalformedMessagesTraceLevel のブール型プロパティを公開する AppDomainInfo インスタンスにアクセスします。 そのため、メッセージ ログ用にトレース リスナーを構成し、これらのオプションを構成で false に設定した場合は、後でアプリケーションの実行時に true に変更できます。 これにより、実行時にメッセージのログ記録が効果的に有効になります。 同様に、構成ファイルでメッセージ ログを有効にした場合は、WMI を使用して実行時に無効にすることができます。

メッセージ ログのメッセージ ログ トレース リスナーがない場合、またはトレースの System.ServiceModel トレース リスナーが構成ファイルに指定されていない場合、変更は WMI によって受け入れられても、どの変更も有効になりません。 それぞれのリスナーを適切に設定する方法の詳細については、「 メッセージ ログの構成」 および 「トレースの構成」を参照してください。 構成で指定された他のすべてのトレース・ソースのトレース・レベルは、アプリケーションの始動時に有効であり、変更することはできません。

WCF では、スクリプト作成のための GetOperationCounterInstanceName メソッドが公開されています。 このメソッドは、操作名を指定すると、パフォーマンス カウンターのインスタンス名を返します。 ただし、入力は検証されません。 したがって、正しくない操作名を指定すると、正しくないカウンター名が返されます。

Service インスタンスの OutgoingChannel プロパティは、宛先サービスへの WCF クライアントが Service メソッド内で作成されていない場合、サービスによって開かれたチャネルが別のサービスに接続するために開かれたチャネルをカウントしません。

注意 WMI では、小数点以下 3 桁までの TimeSpan 値のみがサポートされます。 たとえば、サービスのプロパティの 1 つを MaxValue に設定した場合、WMI で表示すると、その値は小数点以下 3 桁で切り捨てられます。

安全

WCF WMI プロバイダでは、環境内のサービスの検出が許可されるため、アクセスを許可する際には細心の注意を払う必要があります。 デフォルトの管理者のみのアクセスを緩和すると、信頼度の低い関係者が環境内の機密データにアクセスできるようになる可能性があります。 具体的には、リモート WMI アクセスのアクセス許可を緩めると、フラッディング攻撃が発生する可能性があります。 プロセスが過剰な WMI 要求によってフラッディングされると、そのパフォーマンスが低下する可能性があります。

さらに、MOF ファイルに対するアクセス許可を緩和すると、信頼度の低いパーティが WMI の動作を操作し、WMI スキーマに読み込まれるオブジェクトを変更できます。 たとえば、重要なデータを管理者から隠したり、入力されていないフィールドや例外の原因となるフィールドをファイルに追加したりするために、フィールドを削除することができます。

既定では、WCF WMI プロバイダーは、管理者に対して "メソッドの実行"、"プロバイダー書き込み"、および "アカウントの有効化" アクセス許可を付与し、ASP.NET、ローカル サービス、およびネットワーク サービスに対して "アカウントの有効化" アクセス許可を付与します。 特に、Windows Vista 以外のプラットフォームでは、ASP.NET アカウントは WMI ServiceModel 名前空間への読み取りアクセス権を持っています。 これらの特権を特定のユーザー グループに付与しない場合は、WMI プロバイダーを非アクティブ化するか (既定では無効になっています)、特定のユーザー グループのアクセスを無効にする必要があります。

また、構成を使用して WMI を有効にしようとすると、ユーザー特権が不十分なために WMI が有効にならない場合があります。 ただし、この失敗を記録するイベントはイベント ログに書き込まれません。

ユーザー特権レベルを変更するには、次の手順に従います。

  1. [スタート] をクリックし、[ファイル名を指定して実行] をクリックして、「 compmgmt.msc」と入力します。

  2. [サービスとアプリケーション/WMI コントロール] を右クリックして [プロパティ] を選択します。

  3. [セキュリティ] タブを選択し、Root/ServiceModel 名前空間に移動します。 [ セキュリティ] ボタンをクリックします。

  4. アクセスを制御する特定のグループまたはユーザーを選択し、[ 許可 ] または [拒否 ] チェックボックスを使用してアクセス許可を構成します。

追加のユーザーに対する WCF WMI 登録アクセス許可の付与

WCF は、管理データを WMI に公開します。 これは、インプロセス WMI プロバイダー ("分離プロバイダー" と呼ばれることもあります) をホストすることによって行われます。 管理データを公開するには、このプロバイダーを登録するアカウントに適切なアクセス許可が必要です。 Windows では、既定では、少数の特権アカウントのみが分離されたプロバイダーを登録できます。 これは、ユーザーが通常、既定のセットに含まれていないアカウントで実行されている WCF サービスから WMI データを公開することを望んでいるため、問題です。

このアクセス権を付与するには、管理者が追加のアカウントに次のアクセス許可を次の順序で付与する必要があります。

  1. WCF WMI 名前空間にアクセスするためのアクセス許可。

  2. WCF 分離 WMI プロバイダーを登録するためのアクセス許可。

WMI 名前空間のアクセス許可を付与するには

  1. 次の PowerShell スクリプトを実行します。

    write-host ""  
    write-host "Granting Access to root/servicemodel WMI namespace to built in users group"  
    write-host ""  
    
    # Create the binary representation of the permissions to grant in SDDL  
    $newPermissions = "O:BAG:BAD:P(A;CI;CCDCLCSWRPWPRCWD;;;BA)(A;CI;CC;;;NS)(A;CI;CC;;;LS)(A;CI;CC;;;BU)"  
    $converter = new-object system.management.ManagementClass Win32_SecurityDescriptorHelper  
    $binarySD = $converter.SDDLToBinarySD($newPermissions)  
    $convertedPermissions = ,$binarySD.BinarySD  
    
    # Get the object used to set the permissions  
    $security = gwmi -namespace root/servicemodel -class __SystemSecurity  
    
    # Get and output the current settings  
    $binarySD = @($null)  
    $result = $security.PsBase.InvokeMethod("GetSD",$binarySD)  
    
    $outsddl = $converter.BinarySDToSDDL($binarySD[0])  
    write-host "Previous ACL: "$outsddl.SDDL  
    
    # Change the Access Control List (ACL) using SDDL  
    $result = $security.PsBase.InvokeMethod("SetSD",$convertedPermissions)
    
    # Get and output the current settings  
    $binarySD = @($null)  
    $result = $security.PsBase.InvokeMethod("GetSD",$binarySD)  
    
    $outsddl = $converter.BinarySDToSDDL($binarySD[0])  
    write-host "New ACL:      "$outsddl.SDDL  
    write-host ""  
    

    この PowerShell スクリプトでは、セキュリティ記述子定義言語 (SDDL) を使用して、Built-In Users グループに "root/servicemodel" WMI 名前空間へのアクセス権を付与します。 次の ACL を指定します。

    • Built-In 管理者 (BA) - 既にアクセス権があります。

    • ネットワークサービス(NS) - すでにアクセスがありました。

    • ローカルシステム (LS) - すでにアクセス権がありました。

    • Built-In ユーザー - アクセス権を付与するグループ。

プロバイダー登録アクセス権を付与するには

  1. 次の PowerShell スクリプトを実行します。

    write-host ""  
    write-host "Granting WCF provider registration access to built in users group"  
    write-host ""  
    # Set security on ServiceModel provider  
    $provider = get-WmiObject -namespace "root\servicemodel" __Win32Provider  
    
    write-host "Previous ACL: "$provider.SecurityDescriptor  
    $result = $provider.SecurityDescriptor = "O:BUG:BUD:(A;;0x1;;;BA)(A;;0x1;;;NS)(A;;0x1;;;LS)(A;;0x1;;;BU)"  
    
    # Commit the changes and display it to the console  
    $result = $provider.Put()  
    write-host "New ACL:      "$provider.SecurityDescriptor  
    write-host ""  
    

任意のユーザーまたはグループにアクセス権を付与する

このセクションの例では、WMI プロバイダーの登録特権をすべてのローカル ユーザーに付与します。 組み込みされていないユーザーまたはグループにアクセス権を付与する場合は、そのユーザーまたはグループのセキュリティ識別子 (SID) を取得する必要があります。 任意のユーザーのSIDを取得する簡単な方法はありません。 1 つの方法は、目的のユーザーとしてログオンし、次のシェル コマンドを発行することです。

Whoami /user  

詳細については、「 既知の SID」を参照してください

リモート WMI オブジェクト インスタンスへのアクセス

リモート コンピューター上の WCF WMI インスタンスにアクセスする必要がある場合は、アクセスに使用するツールでパケット プライバシーを有効にする必要があります。 次のセクションでは、WMI CIM Studio、Windows Management Instrumentation Tester、および .NET SDK 2.0 を使用してこれらを実現する方法について説明します。

WMI CIM スタジオ

WMI 管理ツールをインストールした場合は、WMI CIM Studio を使用して WMI インスタンスにアクセスできます。 ツールは次のフォルダにあります。

%windir%\Program Files\WMI ツール\

  1. [ 名前空間に接続] ウィンドウで、「 root\ServiceModel 」と入力し、[OK] をクリックします

  2. WMI CIM Studio の [ログイン] ウィンドウで、[オプション] >> ボタンをクリックしてウィンドウを展開します。 [認証レベル] で [パケットのプライバシー] を選択し、[OK] をクリックします。

Windows Management Instrumentation テスター

このツールはWindowsによってインストールされます。 これを実行するには、[スタート/実行] ダイアログ ボックスに「cmd.exe」と入力してコマンド コンソールを起動し、[OK] をクリックします。 次に、コマンド ウィンドウに 「wbemtest.exe 」と入力します。 その後、Windows Management Instrumentation Tester ツールが起動します。

  1. ウィンドウの右上隅にある[ 接続 ]ボタンをクリックします。

  2. 新しいウィンドウで、[名前空間] フィールドに「root\ServiceModel」と入力し、[認証レベル] で [パケットのプライバシー] を選択します。 [接続] をクリックします。

マネージ コードの使用

また、 System.Management 名前空間によって提供されるクラスを使用して、プログラムでリモート WMI インスタンスにアクセスすることもできます。 次のコード サンプルは、これを行う方法を示しています。

String wcfNamespace = $@"\\{this.serviceMachineName}\Root\ServiceModel");
  
ConnectionOptions connection = new ConnectionOptions();  
connection.Authentication = AuthenticationLevel.PacketPrivacy;  
ManagementScope scope = new ManagementScope(this.wcfNamespace, connection);