WMI 的
Win32_PerfRawData 为我们提供了监控系统性能的相关参数。但是有些时候这些类的属性返回值不能直接使用。比如在监控网卡流量
Win32_PerfRawData_Tcpip_NetworkInterface 时
BytesReceivedPersec BytesSentPersec 有时候会返回负值。难道是程序出错了么?其实其原因是,
Win32_PerfRawData 类正如其名称所暗示的:它们是“原始”数据类,这意味着返回的值并不一定是最终的值。您通常需要对其进行“修正”;也就是说,您必须通过某种数学公式对返回的数值进行计算以便获得真正的值。
那数学公式到底是什么呢?WMI把各种性能参数按照性能计数器类型。不同计数器类型使用不同的公式。具体分类如下:
计数器类型 | XP 上的实例 | 2003 上的实例 |
---|---|---|
PERF_COUNTER_RAWCOUNT | 475 | 750 |
PERF_COUNTER_COUNTER | 211 | 320 |
PERF_COUNTER_LARGE_RAWCOUNT | 97 | 122 |
PERF_COUNTER_BULK_COUNT | 63 | 78 |
PERF_RAW_FRACTION | 13 | 30 |
PERF_100NSEC_TIMER | 23 | 23 |
PERF_PRECISION_100NS_TIMER | 8 | 8 |
PERF_AVERAGE_BULK | 6 | 6 |
PERF_AVERAGE_TIMER | 6 | 6 |
PERF_COUNTER_100NS_QUELEN_TYPE | 6 | 6 |
PERF_SAMPLE_FRACTION | 0 | 5 |
PERF_ELAPSED_TIME | 4 | 4 |
PERF_COUNTER_TIMER | 0 | 2 |
PERF_100NSEC_TIMER_INV | 1 | 1 |
PERF_COUNTER_RAWCOUNT_HEX | 1 | 1 |
PERF_COUNTER_LARGE_RAWCOUNT_HEX | 1 | 1 |
PERF_COUNTER_LARGE_QUELEN_TYPE | 0 | 0 |
PERF_COUNTER_TIMER_INV | 0 | 0 |
PERF_COUNTER_TEXT | 0 | 0 |
PERF_COUNTER_MULTI_TIMER_INV | 0 | 0 |
PERF_COUNTER_DELTA | 0 | 0 |
PERF_COUNTER_LARGE_DELTA | 0 | 0 |
PERF_SAMPLE_COUNTER | 0 | 0 |
PERF_COUNTER_QUELEN_TYPE | 0 | 0 |
PERF_PRECISION_SYSTEM_TIMER | 0 | 0 |
PERF_OBJ_TIME_TIMER | 0 | 0 |
PERF_COUNTER_MULTI_TIMER | 0 | 0 |
PERF_100NSEC_MULTI_TIMER | 0 | 0 |
PERF_100NSEC_MULTI_TIMER_INV | 0 | 0 |
PERF_COUNTER_OBJ_TIME_QUELEN_TYPE | 0 | 0 |
如果看一下该表,您会发现一些有趣的事情:六种计数器类型(PERF_COUNTER_RAWCOUNT、 PERF_COUNTER_COUNTER、 PERF_COUNTER_LARGE_RAWCOUNT、PERF_COUNTER_BULK_COUNT、PERF_RAW_FRACTION 和 PERF_100NSEC_TIMER)几乎涵盖了 Windows XP 和 Windows Server 2003 上使用的所有性能计数器。这六种类型中PERF_COUNTER_RAWCOUNT 和 PERF_COUNTER_LARGE_RAWCOUNT不需要任何计算;您可以直接使用返回的值。PERF_COUNTER_COUNTER 和 PERF_COUNTER_BULK_COUNT使用相同的公式。我们只需了解三个公式。这样,就将能够监视性能输出争取的返回值
具体那个类型对应那个公式如下:
PERF_RAW_FRACTION
(100 * CounterValue) / BaseValue
BaseValue 可以通过wbemtest.exe去查
PERF_COUNTER_COUNTER
(CounterValue2 - CounterValue1) / ((TimeValue2 - TimeValue1) / TimeBase)
- TimeStamp_PerfTime 。这是我们的开始时间(即,TimeValue)
- Frequency_PerfTime 。这是我们的 TimeBase
具体的例子如下:
On Error Resume Next
strComputer = "."
Set objArgs = wscript.Arguments
strComputer = objArgs.item(0)
Set objWMIService = GetObject("winmgmts://" & strComputer & "/root/cimv2")
wqlQuery = "select * from Win32_PerfRawData_Tcpip_NetworkInterface where Name='Broadcom BCM5708C NetXtreme II GigE [NDIS VBD Client] - 数据包计划程序微型端口'" '查询指定网卡接口的实例
strComputer = "."
Set objArgs = wscript.Arguments
strComputer = objArgs.item(0)
Set objWMIService = GetObject("winmgmts://" & strComputer & "/root/cimv2")
wqlQuery = "select * from Win32_PerfRawData_Tcpip_NetworkInterface where Name='Broadcom BCM5708C NetXtreme II GigE [NDIS VBD Client] - 数据包计划程序微型端口'" '查询指定网卡接口的实例
Set colItems = objWMIService.ExecQuery(wqlQuery ,,48)
For Each objItem in colItems
For Each objItem in colItems
recieve_value1=objItem.BytesReceivedPersec
send_value1=objItem.BytesSentPersec
timevalue1=objItem.Timestamp_PerfTime
timeBase = objItem.Frequency_PerfTime
Next
Wscript.Sleep(1000)
Set colItems = objWMIService.ExecQuery(wqlQuery ,,48)
For Each objItem in colItems
recieve_value2=objItem.BytesReceivedPersec
send_value2=objItem.BytesSentPersec
timevalue2=objItem.Timestamp_PerfTime
Next
send_value1=objItem.BytesSentPersec
timevalue1=objItem.Timestamp_PerfTime
timeBase = objItem.Frequency_PerfTime
Next
Wscript.Sleep(1000)
Set colItems = objWMIService.ExecQuery(wqlQuery ,,48)
For Each objItem in colItems
recieve_value2=objItem.BytesReceivedPersec
send_value2=objItem.BytesSentPersec
timevalue2=objItem.Timestamp_PerfTime
Next
recieve=(recieve_value2-recieve_value1)/CInt((timevalue2-timevalue1)/timeBase)
send=(send_value2-send_value1)/CInt((timevalue2-timevalue1)/timeBase)
send=(send_value2-send_value1)/CInt((timevalue2-timevalue1)/timeBase)
wscript.echo CStr(send)
wscript.echo CStr(recieve)
wscript.echo Date() & " " & Time()
wscript.echo CStr(recieve)
wscript.echo Date() & " " & Time()
wscript.echo "send kbps"
wscript.echo "recieve kbps"
wscript.echo "recieve kbps"
PERF_100NSEC_TIMER
100* (CounterValue2 - CounterValue1) / (TimeValue2 - TimeValue1)
使用 TimeStamp_Sys100NS 来确定时间间隔,而不是使用 TimeStamp_PerfTime 属性
查询性能计数器类型的方法如下
strComputer = "."
strNamespace = "root/cimv2"
Set objWMIService = GetObject("winmgmts://" & strComputer & "/root/cimv2")
For Each objclass2 in objWMIService.SubclassesOf()
If Left(objClass2.Path_.Class,13) = "Win32_PerfRaw" Then
strClass = objClass2.Path_.Class
Set objClass = GetObject("winmgmts://" & strComputer & _
"/" & strNameSpace & ":" & strClass)
For Each objClassProperty In objClass.Properties_
strType = ""
strFormula = ""
For Each objClassQualifier In objClassProperty.Qualifiers_
If objClassQualifier.Name = "countertype" Then
Select Case objClassQualifier.Value
Case 0
strType = "PERF_COUNTER_RAWCOUNT_HEX"
Case 1073874176
strType = "PERF_AVERAGE_BULK"
Case 1073939457
strType = "PERF_SAMPLE_BASE"
Case 1073939458
strType = "PERF_AVERAGE_BASE"
Case 1073939459
strType = "PERF_RAW_BASE"
Case 1073939712
strType = "PERF_LARGE_RAW_BASE"
Case 1107494144
strType = "PER_COUNTER_MULTI_BASE"
Case 256
strType = "PERF_COUNTER_LARGE_RAWCOUNT_HEX"
Case 272696320
strType = "PERF_COUNTER_COUNTER"
Case 272696576
strType = "PERF_COUNTER_BULK_COUNT"
Case 2816
strType = "PERF_COUNTER_TEXT"
Case 591463680
strType = "PERF_COUNTER_MULTI_TIMER_INV"
Case 4195238
strType = "PERF_COUNTER_DELTA"
Case 4195584
strType = "PERF_COUNTER_LARGE_DELTA"
Case 4260864
strType = "PERF_SAMPLE_COUNTER"
Case 4523008
strType = "PERF_COUNTER_QUELEN_TYPE"
Case 537003008
strType = "PERF_RAW_FRACTION"
Case 541525248
strType = "PERF_PRECISION_SYSTEM_TIMER"
Case 558957824
strType = "PERF_100NSEC_TIMER_INV"
Case 542180608
strType = "PERF_100NSEC_TIMER"
Case 542573824
strType = "PERF_PRECISION_100NS_TIMER"
Case 543229184
strType = "PERF_OBJ_TIME_TIMER"
Case 549585920
strType = "PERF_SAMPLE_FRACTION"
Case 4523264
strType = "PERF_COUNTER_LARGE_QUELEN_TYPE"
Case 5571840
strType = "PERF_COUNTER_100NS_QUELEN_TYPE"
Case 541132032
strType = "PERF_COUNTER_TIMER"
Case 574686464
strType = "PERF_COUNTER_MULTI_TIMER"
Case 575735040
strType = "PERF_100NSEC_MULTI_TIMER"
Case 592512256
strType = "PERF_100NSEC_MULTI_TIMER_INV"
Case 65536
strType = "PERF_COUNTER_RAWCOUNT"
Case 65792
strType = "PERF_COUNTER_LARGE_RAWCOUNT"
Case 6620416
strType = "PERF_COUNTER_OBJ_TIME_QUELEN_TYPE"
Case 805438464
strType = "PERF_AVERAGE_TIMER"
Case 807666944
strType = "PERF_ELAPSED_TIME"
Case 557909248
strType = "PERF_COUNTER_TIMER_INV"
Case Else
strType = "无法确定计数器类型。"
End Select
End If
Next
WScript.Echo strClass & "." & objClassProperty.Name & "," & strType
Next
End If
Next
http://www.wangjianying.com/html/aea326ad8b198795.html