[WMI]Win32_PerfRawData_Tcpip_NetworkInterfaceは名称が重複したNICがある環境では各カウンタの実体を識別することができない(制限事項)

本日のトピックは、WMI の クラスの組み合わせで発生する制限事項についてのお話となります。

[今日のテーマ] WMI の Win32_NetworkAdapter や Win32_NetworkAdapterConfigration クラスでは、同じ名称でシステムに登録されているアダプタがある場合、Name プロパティは登録名からそのままもってくるため、値が重複して取得されてしまう。このように複数同じ名前で登録されたネットワーク アダプタが存在するシステムでは、Win32_PerfRawData_Tcpip_NetworkInterface (Win32_PerfFormattedData_Tcpip_NetworkInterface) クラスのカウンタと結びつけることができない。

はじめに : NIC 自身のシステムへの登録の仕方に Name プロパティの取得結果が影響される
システムに登録されたネットワーク カード (NIC) の情報を採取する際に WMI の Win32_NetworkAdapterConfiguration および Win32_NetworkAdapter クラスを使用する例は多くあります。しかし、これらのクラスの Name や Description プロパティだけでは複数の同じ種類の NIC それぞれを識別する指標にはなりえません。

Name や Description プロパティなど、上記の WMI のクラスが返すプロパティ情報は、その環境の NIC がセットアップされる際にどのように自身の情報をシステムに登録したかに依存します。 つまり、同じ種類の NIC を複数セットアップする際に、システムにそれぞれの NIC 毎に同じ名前で登録してしまう作りのデバイスの場合、Name や Description プロパティの値がすべていっしょということも起こりうるということになります。アダプタによっては、システム登録時複数同じ種類のアダプタが存在していても #1 、#2 のように識別子を付けず同じ名前で登録してしまうものがあるのです。

image

図 : NIC によっては同じ名前でレジストリに登録してしまうものもありえる。ただし、デバイス ID は固有。

名前が重複するインスタンスそれぞれを見分けるための指標とは
こうした「同じ名前のインスタンスそれぞれ、同じ名前でプロパティが返ってきてしまう」ということは Win32_NetworkAdapter や Win32_NetworkAdapterConfigration クラス以外にもよくあります。一番身近な例としては、Win32_Process クラスです。システム上に、notepad.exe や svchost.exe など複数の同じ名前のプロセスが起動していることはごく普通にあるシチュエーションです。こうしたクラスでは、ほかにインスタンス(それぞれのデバイス、それぞれのプロセス)を特定するためのユニークな ID 情報のプロパティがありますので、そちらを使って個別の判定をします。

・Win32_NetworkAdapter … DeviceID プロパティ
・Win32_NetworkAdapterConfigration … SettingID プロパティ
・Win32_Process … processID プロパティ など

通常はデバイスやプロセスなどの個別の実体を把握するには、これらのユニークな値を返すプロパティ値を基準にします。

Win32_PerfRawData_Tcpip_NetworkInterface (Win32_PerfFormattedData_Tcpip_NetworkInterface) クラスのインスタンス識別が事実上できないのはなぜか
Win32_PerfRawData_Tcpip_NetworkInterface および Win32_PerfFormattedData_Tcpip_NetworkInterface クラスは、パフォーマンス モニターのエンジンを通じて NIC のパフォーマンス情報を取得します。ところが、この際に以下の点に注意しなくてはなりません。

・Win32_PerfRawData_Tcpip_NetworkInterface (Win32_PerfFormattedData_Tcpip_NetworkInterface) クラスはパフォーマンス モニターの GUI 上の見た目をそのまま引き継ぐわけではない
・各 NIC のインスタンス識別は、同クラスの Name や Description プロパティを用いるほかにないが、これらは複数同じ名前でネットワーク アダプタが登録されたシステムではすべて同じになってしまう。(※)

しかし、残念ながら Win32_PerfRawData_Tcpip_NetworkInterface (Win32_PerfFormattedData_Tcpip_NetworkInterface) クラスは DeviceID や SettingID をインターフェースに持たないため、事実上これらのクラスの各 NIC のインスタンスを識別しきれないということになります。(※ Captionプロパティの頭には識別子がつきますが、Win32_Perf… クラスの Name 自体に識別子を持たないため、結局どれがどれなのか判別できません)

image

<データを識別できないパターン>
・複数の Win32_PerfRawData_Tcpip_NetworkInterface インスタンスが同じ Name プロパティを持つ
・複数の Win32_NetworkAdapterConfiguration インスタンスが同じ Description プロパティを持つ

Description プロパティの元になるのはレジストリですが、レジストリ キーは環境や NIC によって異なる値の可能性がある上、値を変更することでその NIC の情報に依存したアプリケーションがある場合も含め、システム上の影響としてどのような状況に至るかはケースバイケースになる上、書き換えたはずのレジストリが再度書き換えられる、あるいは別にレジストリがまた作られるような動作をする場合もあります。そのため、環境側から名前を書き換えることは推奨しません。

image

図 : レジストリに登録されたデータが重複していると取得結果も重複する

パフォーマンス モニター上では NIC が識別されるのに、なぜ WMI のクラスでは識別子がついてない状態になるのか
なお、このように元データが重複している環境でも、パフォーマンス モニター上では、各 NIC のデータはちゃんと #1、#2… のように識別できる状態で表示されています。しかし、これはパフォーマンス モニタが出力する際に内部でそれぞれの実体を識別し、識別子を付けた状態で表示させる実装をしているためです。残念ながら、パフォーマンス モニタ側の識別子ありの状態のデータを扱うためのインターフェースは公開されていないため、事実上プログラム側では識別ができない状態は変わりありません。

image

参考 : Win32_Process クラスと Win32_PerfRawData_PerfProc_Process (Win32_PerfFormattedData_PerfProc_Process)
一方、同じく Name プロパティが重複して帰ってくるプロセスの場合を見てみますと、Win32_PerfRawData_PerfProc_Process および Win32_PerfFormattedData_PerfProc_Process クラスでは、Caption のほか、プロセス ID に対してもインターフェースを解放しています (IDProcess)。プロセス ID は文字通りインスタンス固有の情報ですのでそもそも Caption ではなく ID を使うことで識別ができます。そのため、ネットワーク アダプタのように、名称が重複しても識別できない状況にはなりません。

*****

残念ながら、この動作は製品の既定の動作となります。また、NIC の名称を重複させてはいけないという制限事項もないため、NICのハードウエアメーカー様の設計次第でそのシステム上で動作するソフトウエア(含む OS のモジュール、たとえば今回の WMI など)が今回のように影響されてしまう状況が全くないと言いきれません。

上記のようなシナリオでプログラムを設計されている場合はこうした構成にご注意ください。

(WMI Programming Support Team – May 04, 2011)