Const EVENT_ID_SUCCESS = 1000 'Use IDs in the range 1 - 1000
Const EVENT_ID_SCRIPTERROR = 999 'Then you can use eventcreate.exe to test the MP
'Global vars
Dim mblnLogSuccessEvent 'As Boolean
Dim mstrIdentifier 'As String
Call Main
'*********************************************************************************************
' PROCEDURE: Main
' DESCRIPTION: Reads the script parameters and creates the cluster disk monitoring data.
' PARAMETERS: void
'*********************************************************************************************
Private Sub Main()
' Targeted at Microsoft.Windows.Cluster.VirtualServer (based on Microsoft.Windows.Server.Computer)
Dim objFSO 'As Scripting.FileSystemObject
Dim boolNoMonitoredClusterDiskAvailable
Dim strTargetComputer 'As String '= oArgs(6)
Dim strClusterName 'As String '= oArgs(7)
Dim objMomScriptAPI 'As MOM.ScriptAPI
Dim blnSuccess 'As Boolean
Dim strErrorMessage
On Error Resume Next
Err.Clear
Set objMomScriptAPI = CreateObject("MOM.ScriptAPI")
If Err.Number <> 0 Then
Exit Sub
End If
If Not GetScriptParameters(strTargetComputer, strClusterName) Then
' If the script is called without the required arguments,
' create an information event and then quit.
strErrorMessage = "The script was called with fewer than four arguments or the arguments could not be parsed."
Call LogScriptEvent(0, EVENT_ID_SCRIPTERROR, EVENT_TYPE_WARNING, strErrorMessage,objMomScriptAPI)
WScript.Quit(-1)
End If
If blnSuccess Then
If mblnLogSuccessEvent Then
strErrorMessage = "Script executed successfully."
Call LogScriptEvent(0, EVENT_ID_SUCCESS, EVENT_TYPE_INFORMATION, strErrorMessage,objMomScriptAPI)
End If
'Return the typed property bags
If boolNoMonitoredClusterDiskAvailable = true Then
CreateEmptyTypedPropertyBag(objMomScriptAPI)
End If
Else
CreateEmptyTypedPropertyBag(objMomScriptAPI)
strErrorMessage = "TAn error occurred while running script"
Call LogScriptEvent(0, EVENT_ID_SCRIPTERROR, EVENT_TYPE_WARNING, strErrorMessage,objMomScriptAPI)
End If
Call objMomScriptAPI.ReturnItems
Set objMomScriptAPI = Nothing
End Sub
'****************************************************************************************************************
' FUNCTION: GetRegistryKeyValue
' DESCRIPTION: Get Registry Key value.
' PARAMETERS: IN String keyPath: Path to search in registry.
' IN String Key: key to return value from
' RETURNS: string: Value if successful
'****************************************************************************************************************
Function GetRegistryKeyValue(ByVal keyPath, ByVal key)
Dim oReg, strKeyValue
strKeyValue = ""
GetRegistryKeyValue = strKeyValue
On Error Resume Next
Err.Clear
Set oReg = CreateObject("WScript.Shell")
If Err.Number <> 0 Then
Err.Clear
Exit Function
End If
strKeyValue = oReg.RegRead(keyPath & key)
If Err.Number <> 0 Then
Exit Function
End If
GetRegistryKeyValue = strKeyValue
' resume error
On Error Goto 0
End Function
'****************************************************************************************************************
' FUNCTION: MonitorClusterDisks
' DESCRIPTION: Creates monitoring data for all instances of the class 'Microsoft.Windows.Server.ClusterDisksMonitoring.ClusterDisk' using WMI.
' PARAMETERS: IN String strTargetComputer: principal name of the targeted 'Microsoft.Windows.Cluster.VirtualServer' instance.
' IN String strClusterName: the cluster containing the cluster shared volume
' RETURNS: Boolean: True if successful
'****************************************************************************************************************
Private Function MonitorClusterDisks(ByRef strTargetComputer, ByRef strClusterName, ByRef objMomScriptAPI, ByRef boolNoMonitoredClusterDiskAvailable) 'As Boolean
Dim objMSClusterSWbemServices 'As SWbemServices
Dim objClusterResources 'As SWbemObject
Dim objClusterResource 'As SWbemObject
Dim objClusterDisk 'As SWbemObject
Dim objClusterDiskPartition 'As SWbemObject
Dim objClusterDisks 'As SWbemObject
Dim objClusterDiskPartitions 'As SWbemObject
Dim blnSuccess 'As Boolean
Dim strOSVersion
Dim strWMIQuery
Dim InstancesCount
'Connect to WMI NS \\.\root\MSCluster
If Not ConnectToWbemNS(".", WMI_MSCLUSTER_NAMESPACE, objMSClusterSWbemServices) Then
boolNoMonitoredClusterDiskAvailable = true
Exit Function
End If
'Adding OS Validation to use propert WMI query to get correct instances
'ResourceClass and IsClusterSharedVolume properties are not available in Windows 2008 OS, only 2008 R2 and beyond.
If (0 = Len(strOSVersion)) Then
Exit Function
End If
If (strOSVersion = "6.0") Then
strWMIQuery = "select * from " & WMI_MSCLUSTER_CLUSTER_RESOURCE
'& " where CoreResource = FALSE"
Else
strWMIQuery = "select * from " & WMI_MSCLUSTER_CLUSTER_RESOURCE & " where ResourceClass = 1 and IsClusterSharedVolume = FALSE"
'"and CoreResource = FALSE"
End If
Set objClusterResources = objMSClusterSWbemServices.ExecQuery(strWMIQuery)
If (Err.Number <> 0 Or Not HasValue(objClusterResources) ) Then
Exit Function
End If
'Loop through all returned cluster resources
For Each objClusterResource In objClusterResources
If (Err.Number <> 0) Then
Set objClusterResources = Nothing
Exit Function
End If
'Get the associated disk partition
Set objClusterDisks = objClusterResource.Associators_(WMI_CLUSTER_RESOURCE_TO_DISK_ASSOCIATOR_CLASS, "", "", "", False, False, "", "", 0)
If (Err.Number <> 0 Or Not HasValue(objClusterDisks) ) Then
Set objClusterDisks = Nothing
Set objClusterResources = Nothing
Exit Function
End If
For Each objClusterDisk In objClusterDisks 'Get the associated resource
If (Err.Number <> 0) Then
Set objClusterDisks = Nothing
Set objClusterResources = Nothing
Exit Function
End If
Set objClusterDiskPartitions = objClusterDisk.Associators_(WMI_CLUSTER_DISKPARTITION_TO_DISK_ASSOCIATOR_CLASS, "", "", "", False, False, "", "", 0)
If (Err.Number <> 0 Or Not HasValue(objClusterDiskPartitions)) Then
Set objClusterDiskPartitions = Nothing
Set objClusterDisks = Nothing
Set objClusterResources = Nothing
Exit Function
End If
For Each objClusterDiskPartition In objClusterDiskPartitions
If (Err.Number <> 0 ) Then
Set objClusterDiskPartitions = Nothing
Set objClusterDisks = Nothing
Set objClusterResources = Nothing
Exit Function
End If
InstancesCount = InstancesCount + 1
blnSuccess = CreateMonitoringData(objClusterDisk, objClusterDiskPartition, objClusterResource,strTargetComputer, strClusterName, objMomScriptAPI)
If (Err.Number <> 0 Or false = blnSuccess) Then
Set objClusterDiskPartitions = Nothing
Set objClusterDisks = Nothing
Set objClusterResources = Nothing
Exit Function
End If
Next 'objClusterDiskPartition
Next 'objClusterDisk
Next 'objClusterResource
Set objClusterDiskPartitions = Nothing
Set objClusterDisks = Nothing
Set objClusterResources = Nothing
On Error Goto 0
End Function
'****************************************************************************************************************
' FUNCTION: CreateMonitoringData
' DESCRIPTION: Create monitoring data for a cluster shared volume.
'
' PARAMETERS: IN Object objClusterResource: the cluster disks as SWbemObject of type MSCluster_Disk.
' IN Object objClusterDiskPartition: the associated disk partition as SWbemObject of type MSCluster_DiskPartition.
' IN Object objClusterResource: the associated cluster resource as SWbemObject of type MSCluster_Resource.
' IN String strTargetComputer: the principal name of the targeted cluster virtual server hosting the cluster shared volume,
' i.e. the cluster name and not the current owner!
' IN String strClusterName: the cluster containing the cluster shared volume
' RETURNS: Boolean: True if successful
'****************************************************************************************************************
Private Function CreateMonitoringData(ByRef objClusterDisk, ByRef objClusterDiskPartition, ByRef objClusterResource, _
ByRef strTargetComputer, ByRef strClusterName, ByRef objMomScriptAPI) 'As Boolean
'Create performance data
Dim strPartitionName 'As String
CreateMonitoringData = False
On Error Resume Next
Err.Clear
strPartitionName = objClusterResource.Properties_(WMI_NAME_PROPERTY_NAME) & "_" & objClusterDiskPartition.Properties_(WMI_PATH_PROPERTY_NAME)
If (0 = Err.Number) Then
CreateMonitoringData = True
End If
On Error Goto 0
End Function
'******************************************************************************
' FUNCTION: GetScriptParameters
' DESCRIPTION: Reads the script's parameters
' and sets the global variables.
'
' PARAMETERS: OUT String strTargetComputer: Principal name of executing computer
' (-Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName-)
' OUT String strClusterName: Cluster name
' RETURNS: Boolean: True if successful
'******************************************************************************
Private Function GetScriptParameters(ByRef strTargetComputer, ByRef strClusterName) 'As Boolean
Dim objArguments
On Error Resume Next
'cmdline: <script> True|False <path to debug log> True|False <script id> .MPElement. .Target/Id. .Target/Property[Name="Windows!Microsoft.Windows.Computer"]/PrincipalName.
Set objArguments = WScript.Arguments
If objArguments.Count < 4 Then Exit Function
Err.Clear
'Get parameters and set global variables
mblnLogSuccessEvent = CBool(objArguments(0))
If (Err.Number <> 0 ) Then
mblnLogSuccessEvent = False
End If
If Len(strTargetComputer) > 0 And Len(strClusterName) > 0 Then GetScriptParameters = True
On Error Goto 0
End Function
'***************************************************************************************
' PROCEDURE: CreatePerformanceTypedPropertyBag
' DESCRIPTION: Generates a performance typed property bag and adds it to the script's XML output.
' PARAMETERS: IN String strObjectName: name of the performance object
' IN String strCounterName: name of the performance counter
' IN String strInstanceName: name of the performance counter in instance
' IN Variant varValue: value of the performance counter
' IN String strCSVInstanceName: Friendly volume name of the cluster shared volume
' IN Object objMomScriptAPI: initialised MOM.ScriptAPI object
'***************************************************************************************
Sub CreatePerformanceTypedPropertyBag(ByRef strObjectName, ByRef strCounterName, ByRef strInstanceName, _
ByRef varValue, ByRef strCSVInstanceName, ByRef objMomScriptAPI)
Dim objTypedPropertyBag 'As MOM.ScriptAPI.TypedPropertyBag
'Create a new typed property bag of the performance data type
Set objTypedPropertyBag = objMomScriptAPI.CreateTypedPropertyBag(PERFORMANCE_DATA_TYPE)
'Add the values for the perf counter's object name, counter name, instance name and the value)
Call objTypedPropertyBag.AddValue(PERFORMANCE_OBJECT_NAME, CStr(strObjectName))
Call objTypedPropertyBag.AddValue(PERFORMANCE_COUNTER_NAME, CStr(strCounterName))
Call objTypedPropertyBag.AddValue(PERFORMANCE_INSTANCE_NAME, CStr(strInstanceName))
Call objTypedPropertyBag.AddValue(PERFORMANCE_VALUE_NAME, CStr(varValue))
'Necessary information for the property bag data source filter condition
'to enable Agent cook down
Call objTypedPropertyBag.AddValue(INSTANCE_NAME, CStr(strCSVInstanceName))
'Add the property bag to the script's XML output
Call objMomScriptAPI.AddItem(objTypedPropertyBag)
End Sub
'***************************************************************************************
' PROCEDURE: CreateEmptyTypedPropertyBag
' DESCRIPTION: Generates a empty performance typed property bag and adds it to the script's XML output.
' PARAMETERS: IN Object objMomScriptAPI: initialised MOM.ScriptAPI object
'***************************************************************************************
Sub CreateEmptyTypedPropertyBag(ByRef objMomScriptAPI)
Dim objTypedPropertyBag 'As MOM.ScriptAPI.TypedPropertyBag
'Create a new typed property bag of the performance data type
Set objTypedPropertyBag = objMomScriptAPI.CreateTypedPropertyBag(PERFORMANCE_DATA_TYPE)
'Add the property bag to the script's XML output
Call objMomScriptAPI.AddItem(objTypedPropertyBag)
End Sub
'******************************************************************************
' FUNCTION: ConnectToWbemNs
' DESCRIPTION: Connects to a WMI namespace
' PARAMETERS: IN String strServerName: name of the computer. If empty the local computer will be used.
' IN String strNameSpace: WMI namespace
' OUT Object objSWbemServices: WbemScripting.SWbemServices object connected to the given
' namespace on the given server
' RETURNS: Boolean: True if successful
'******************************************************************************
Private Function ConnectToWbemNS(ByRef strServerName, ByRef strNameSpace, ByRef objSWbemServices) 'As Boolean
ConnectToWbemNS = False
Dim objSWbemLocator 'as WbemScripting.SWbemLocator
On Error Resume Next
'Create a new WMI Locator object
Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator")
IF HasValue(objSWbemLocator) Then
'Connect to WMI namespace on strServerName computer and create WMI Services object
Set objSWbemServices = objSWbemLocator.ConnectServer(strServerName, strNameSpace)
END IF
'If object is initialised function will be successful
ConnectToWbemNS = HasValue(objSWbemServices)
On Error Goto 0
End Function
Private Function HasValue(Value)
Dim bNothing
bNothing = false
IF ( IsObject(Value) ) THEN
IF (Nothing is Value) THEN
bNothing = true
END IF
END IF
HasValue = Not ( IsEmpty(Value) or bNothing or IsNull(Value) )
End Function
Private Function GetLogScriptName()
GetLogScriptName = "-- Cluster Disks Monitoring Script -- " & vbCrLf & vbCrLf & "Script name: " & WScript.ScriptName & vbCrLf & "Version: " & SCRIPT_VERSION & vbCrLf
End Function
'******************************************************************************
' Subroutine: LogScriptEvent
' DESCRIPTION: Logging events to EventSource
' PARAMETERS: IN Integer LogType: 0 - MomScriptApi; 1 - File, 2 - Screen .
' IN String Message: Event Description
' OUT Object objSWbemServices: WbemScripting.SWbemServices object connected to the given
' namespace on the given server
' RETURNS: Boolean: True if successful
'******************************************************************************
Sub LogScriptEvent(LogType,EventId,EventLevel,Message,objMomScriptAPI)
Dim strMessage
Dim sDate
Dim LogScriptName
On Error Resume Next
If (0 = LogType) Then
If (Not HasValue(objMomScriptAPI)) Then
Exit Sub
End If
LogScriptName = GetLogScriptName()
Call objMomScriptAPI.LogScriptEvent(LogScriptName,EventId,EventLevel,Message)
Else
sDate = Now()
strMessage = "" & sDate & Message
If (1 = LogType) Then
WScript.Echo strMessage
End If