views:

140

answers:

2

I'm working on a project to capture various disk performance metrics using VBScript and would like to use a sub procedure with an object as an argument. In the following code samples the object I'm referring to is objitem.AvgDiskQueueLength which will provide a value for the disk queue length. I haven't found a way to make it work since it is recognized as a string and then doesn't capture the value. My goal is to make it easy for anyone to change the counters that are to be captured by only having to make a change in one location(the procedure call argument). The way I'm going about this may not be the best but I'm open to suggestions. The sub procedure call is below.

PerfCounter "Average Disk Queue Length", "disk_queueLength", "objItem.AvgDiskQueueLength"

The following code is the sub procedure.

Sub PerfCounter(CounterDescription, CounterLabel, CounterObject)
  Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_PerfFormattedData_PerfDisk_PhysicalDisk",,48) 
  args_index = args_index + 1
  arrCriteria = split(command_line_args(args_index),",")
  strDriveLetter = UCase(arrCriteria(0))
  intCriticalThreshold = arrCriteria(1)
  intWarningThreshold = arrCriteria(2)
  For Each objItem in colItems
    With objItem
    WScript.Echo "objitem.name = " & objitem.name
    If InStr(objItem.Name, strDriveLetter & ":") > 0 Then
      intChrLocation = InStr(objItem.Name, strDriveletter)
      strInstanceName = Mid(objItem.Name, intChrLocation, 1)
    End If
    If strDriveLetter = strInstanceName AND InStr(objItem.Name, strDriveLetter & ":") > 0 Then
      If intActiveNode = 1  OR Len(intActiveNode) < 1 Then
        WScript.Echo "CounterDescription = " & CounterDescription
        WScript.Echo "CounterLabel = " & CounterLabel
        WScript.Echo "CounterObject = " & CounterObject
        If CInt(CounterOjbect) => CInt(intCriticalThreshold) Then 
          arrStatus(i) = "CRITICAL: " & strDriveLetter & ": " &  CounterDescription
          arrTrendData(i) = CounterLabel & "=" & CounterObject
          intExitCode = 2
          arrExitCode(i) = intExitCode
        ElseIf CInt(CounterOjbect) => CInt(intWarningThreshold) AND CInt(CounterObject) < CInt(intCriticalThreshold) Then
          arrStatus(i) = "WARNING: " & strDriveLetter & ": " & CounterDescription
          arrTrendData(i) = CounterLabel & "=" & CounterObject
          intExitCode = 1
          arrExitCode(i) = intExitCode
        Else
          arrStatus(i) = "OK: " & strDriveLetter & ": " & CounterDescription
          arrTrendData(i) = CounterLabel & "=" & CounterObject
          intExitCode = 0
          arrExitCode(i) = intExitCode
        End If
        Else
          PassiveNode CounterDescription, CounterLabel
        End If
      End If
    End With
  Next
  i = i + 1
  ReDim Preserve arrStatus(i)
  ReDim Preserve arrTrendData(i)
  ReDim Preserve arrExitCode(i)
End Sub

Thanks,

Jason

+2  A: 

Why cant you do this...

PerfCounter "Average Disk Queue Length", "disk_queueLength", objItem.AvgDiskQueueLength
SDX2000
A: 

To pass an object you have to pass an object, not a string.
To make this method work as expected you would have to have the object prior to the procedure call, but in your code example it looks like you are trying to pass an object that you don't have. A working example:

Set objFSO = CreateObject("Scripting.FileSystemObject")
UseFileSystemObject objFSO

Sub UseFileSystemObject( objfso)
 'Now I can use the FileSystemObject in this procedure.
End Sub

But calling the UseFileSystemObject procedure like this will not work,

UseFileSystemObject "objFSO"

because you are passing in a string not an object.
The only way I can think of to accomplish what you want is to use a select statement to write the appropriate attribute of the object, something like this.

Call PerfCounter "Average Disk Queue Length", "disk_queueLength", "AvgDiskQueueLength"

Sub PerfCounter(CounterDescription, CounterLabel, CounterObjectAttribute)
    Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_PerfFormattedData_PerfDisk_PhysicalDisk",,48) 
    For Each objItem in colItems
        Select Case CounterObjectAttribute
            Case "ObjectAttribute1"

            Case "ObjectAttribute2"

            Case "AvgDiskQueueLength"
                Wscript.Echo objItem.AvgDiskQueueLength
        End Select
    Next
End Sub

So in the select you would have to add a case for each attribute that can be used, but it would allow you to pass a string into the procedure. I might be way off on this, but I don't know how you can pass an object if you don't have the object first.

Tester101