I would like to read the WMI performance counter AvgDiskBytesPerTransfer from the WMI Class Win32_PerfRawData_PerfDisk_LogicalDisk in order to monitor the average number of bytes transferred to or from the disk during write or read operations.

Can I do this with an external script?


Article Comments

AvgDiskBytesPerTransfer VBScript

Using a visual basic script, you can check the according WMI class and report the results to PRTG. In PRTG, run the script as an EXE/Script Sensor.

Use at Your Own Risk

In the following, we provide a script, ready for your own adaptations. Please note: We provide this information to experienced users "as it is", without any warranty, and we also cannot support you with customizing your EXE/Script sensors. Please see further documentation within the script.

' ********************************************************************************
' PRTG Custom EXE Sensor, VB Demo Script for  calclulating Average number of bytes 
' transferred to or from the disk during write or read operations via WMI
' ********************************************************************************
' created Feb 2011 for PRTG Network Monitor V8 by Paessler Support Team, www.paessler.com
' This script is Open Source and comes without support and warranty

'************ How it works ***************************************************
' This scripts utilizes the Performance Counter "AvgDiskBytesPerTransfer" from
' the WMI Class "Win32_PerfRawData_PerfDisk_LogicalDisk".
' http://msdn.microsoft.com/en-us/library/aa394307%28v=vs.85%29.aspx.

' "AvgDiskSecPerTransfer" is defined as Type "uint64" and is of CounterType "1073874176" which means 
' "PERF_AVERAGE_BULK" (http://msdn.microsoft.com/en-us/library/aa934332.aspx)
' Results are calculated by the formula "(X1-X0)/(B1-BO)"
' DefaultScale is set to "-2" for this counter. This indicates the power of 10 by which to multiply the counter value 
' before displaying the counter. For example, if Default scale is set to 2, 
' the counter value is multiplied by 100. If Default scale is set to -3, the counter value is divided by 1,000.
' http://msdn.microsoft.com/en-us/library/aa392761%28v=vs.85%29.aspx
' http://msdn.microsoft.com/en-us/library/e8a76594%28v=vs.71%29.aspx

' You can always check with "perfmon.exe' if your calulated values are correct.

'************ IMPORTANT ***************************************************
' This script stores the values of every reading in a file. Make sure the the script has the necessary
' rights to create this file, and perform read and write operations to the file. 
' Each sensor of this kind must have its own file to store its values.

strFile = "c:\temp\sensor02.txt"

Const ForReading = 1
Const ForWriting = 2

'************ Set Your WMI Credentials here ****************
' Leave User and Password blank for local machine

strComputer = "."
strUser = ""
strPassword = ""


strNamespace = "root/cimv2"

Set objLocator = CreateObject("WbemScripting.SWbemLocator")
Set objWMIService = objLocator.ConnectServer(strComputer,strNamespace,strUser,strPassword)


strWQL = "SELECT AvgDiskBytesPerTransfer,AvgDiskBytesPerTransfer_Base,Timestamp_Perftime,Frequency_PerfTime FROM Win32_PerfRawData_PerfDisk_LogicalDisk"
strWQL = strWQL +  " WHERE Name = '_Total'"

Set objResultSet = objWMIService.ExecQuery(strWQL)

For Each obj in objResultSet
 
  iAvgDiskBytesPerTransfer = obj.AvgDiskBytesPerTransfer
  iAvgDiskBytesPerTransfer_Base = obj.AvgDiskBytesPerTransfer_Base
  iTimestamp_Perftime = obj.Timestamp_Perftime
  iFrequency_PerfTime = obj.Frequency_PerfTime

Next


Set objFSO = CreateObject("Scripting.FileSystemObject")

If objFSO.FileExists(strFile) Then
   
   Set objFile = objFSO.OpenTextFile(strFile, ForReading)

   iAvgDiskBytesPerTransferOld = objFile.Readline
   iAvgDiskBytesPerTransfer_BaseOld = objFile.Readline
   iTimestamp_PerftimeOld = objFile.Readline
   iFrequency_PerfTimeOld = objFile.Readline
    
   objFile.Close
   Set objFile = nothing
   
   
   iResult = (iAvgDiskBytesPerTransfer - iAvgDiskBytesPerTransferOld ) * iAvgDiskBytesPerTransfer_Base
   iResult = iResult  / (iTimestamp_PerfTime  -itimeStamp_PerfTimeOld )
   ' iResult = iResult / 100
   iResult = Round(iResult,0)
   
   ' ************* IMPORTANT **********
   ' You may have to replace  the decimal symbol. It must be ".", so uncomment the next line if need be.
   strResult = Replace(CStr(iResult),",",".")
   
   wscript.echo StrResult &":Ok"
    
Else
    Set objFile = objFSO.CreateTextFile(strFile)
    Set objFile = nothing
    wscript.echo "0:Ok"
End If


Set objFile = objFSO.OpenTextFile(strFile, ForWriting)

objFile.WriteLine(iAvgDiskBytesPerTransfer)
objFile.WriteLine(iAvgDiskBytesPerTransfer_Base)
objFile.WriteLine(iTimestamp_Perftime)
objFile.WriteLine(iFrequency_PerfTime)


objFile.Close

Feb, 2011 - Permalink