set psscript=DiscoverClustering.ps1
set vbscript=DiscoverClustering.vbs
set cscript=%windir%\system32\cscript.exe
set ps=%windir%\system32\WindowsPowerShell\v1.0\powershell.exe
set params=
if Exist "%cscript%" goto vb
if Exist "%ps%" goto pshell
goto end
:vb
if not exist "%~dp0%vbscript%" goto end
if exist "%~dp0vbparams.txt" (
set /p params=<"%~dp0vbparams.txt"
)
"%cscript%" /nologo "%~dp0%vbscript%" %params%
goto end
:pshell
if not exist "%~dp0%psscript%" goto end
if exist "%~dp0psparams.txt" (
set /p params=<"%~dp0psparams.txt"
)
"%ps%" -nologo -EP bypass -command "& '%~dp0%psscript%'" %params%
goto end
Function Init-ScomHelper
{
$DiscHelper = @'
namespace SCOM.Helper
{
using System;
using System.Runtime.InteropServices;
public class ConvertData
{
public static string GetDataItemFromOutput(
Object oData)
{
NativeMethods.ISerialize discoverySerializer = null;
discoverySerializer = oData as NativeMethods.ISerialize;
string xmlString = null;
if (null != discoverySerializer)
{
int hr = discoverySerializer.SaveToString(out xmlString);
Marshal.ThrowExceptionForHR(hr);
}
return xmlString;
}
public static class NativeMethods
{
[Guid("A4E79E8A-9494-47A4-A280-8C7D35C88A2F"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ISerialize
{
int SaveToString([MarshalAs(UnmanagedType.BStr)] out string output);
int LoadFromString([MarshalAs(UnmanagedType.BStr)] string input);
}
}
}
}
Function Check-WmiException ([System.Management.ManagementException] $Exception)
{
$WMI_ERROR_INVALIDCLASS = -2147217392
$WMI_ERROR_INVALIDNAMESPACE = -2147217394
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$error.Clear()
Function Check-CimException ( $Exception)
{
$CIM_ERROR_INVALIDCLASS = 2147749902
$CIM_ERROR_INVALIDNAMESPACE = 2147749904
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$error.Clear()
Function Get-ClusterObjects($oCluster,[string]$ComputerName,[string]$AssociatorName,[string]$WmiClassName)
{
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$error.Clear()
$Objects = $null
$Namespace = "root\mscluster"
if ($oNodes.Count -gt 1)
{
$oNodes = $oNodes[0]
}
}
return $oNodes
}
Function Get-ClusterNetworks($oCluster,[string]$ComputerName)
{
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$error.Clear()
$ClassName = "MSCluster_Network"
$AssocName = "MSCluster_ClusterToNetwork"
Function Get-ClusterNetworkInterfaceFromNet($oNet,[string]$ComputerName)
{
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$error.Clear()
$ClassName = "MSCluster_NetworkInterface"
$AssocName = "MSCluster_NetworkToNetworkInterface"
Function Get-ClusterNetInterfaces($oNetwork,[string]$ComputerName)
{
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$error.Clear()
$ClassName = "MSCluster_NetworkInterface"
$AssocName = "MSCluster_NetworkToNetworkInterface"
Function Get-ClusterResourceInGroup($oGroup,[string]$ComputerName)
{
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$error.Clear()
$ClassName = "MSCluster_Resource"
$AssocName = "MSCluster_ResourceGroupToResource"
Function Get-NicFromPs([string]$NetId,[bool]$discoverUnusedNetworks)
{
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$error.Clear()
$result = Load-Module -ModuleName "NetAdapter"
if ($false -eq $result)
{
return $null
}
$Nics = Get-NetAdapter -Name $NetId
if ($false -eq $discoverUnusedNetworks)
{
$Nics = $Nics | where {$_.Status -ne "Disconnected"}
}
return $Nics
}
Function Get-NicData([string]$ComputerName,[string]$NetId,$oObject,[bool]$discoverUnusedNetworks)
{
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$error.Clear()
Function Convert-IntToString($Value,[string]$DefaultValue,[bool]$Hex=$false)
{
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$error.Clear()
Function Discovery-Nodes
(
$oCluster,
[string]$ComputerName,
[string]$NetBiosName,
$oDiscoveryData,
$oClusterInstance
)
{
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$error.Clear()
Function WinClusterNodeDiscoverInstance($hostKey, $oObject, $oDiscoveryData,$ComputerName)
{
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$error.Clear()
$result = $false
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
LogMessage $DBG_TRACE $StartNetworkIfRelDiscoveryMessage
$error.Clear()
$oDiscoveryData.AddInstance($oInstance)
if (0 -ne $error.Count)
{
$deviceID = $null
}
return $deviceID;
}
#============================================================
# Get Network Name from DeviceId
# OS < 2008
# DeviceId=NetName - SystemName
# OS >= 2008
# DeviceId=SystemName - NetName
#===========================================================
Function Get-NetIfName($oNetworkItf)
{
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$error.Clear()
Function Discovery-IsEnabledGroup($oGroup,$GroupTypeFilter,$GroupType)
{
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$error.Clear()
#==========================================================================
# Class: WinClusterObject
# Description: base holding object and its properties
#==========================================================================
#==========================================================================
# Discover instance
#==========================================================================
Function WinClusterObjectDiscoverInstance($hostKey, $ObjectName, $discoveryClass, $oDiscoveryData,[bool]$appendClusterNameToResourceGroup)
{
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$message = $StartWinClusterInstDiscoveryMsg -f $discoveryClass
LogMessage $DBG_TRACE $message
$error.Clear()
Function Discover-Cluster([string]$ClusterName,$oDiscoveryData)
{
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$message = $StartWinClusterDiscoveryMsg -f $ClusterName
LogMessage $DBG_TRACE $message
$error.Clear()
function Get-EmptyDiscoveryData($SourceId, $ManagedEntityId,$IsSnapshot)
{
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$Error.Clear()
if ($null -eq $oAPI)
{
$oAPI = New-Object -ComObject "MOM.ScriptAPI"
if ($null -eq $oAPI)
{
return $null
}
}
Function Log-DiscoveryMessage([string]$message)
{
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$timex=get-date -displayhint time
$message = $message +" " + $timex
LogMessage $DBG_TRACE $message
}
#==========================================================================
# Initialize the arguments in Script
#==========================================================================
Function Initialize-DiscoveryScript
(
[ref]$appendClusterNameToResourceGroup
,[ref]$strNetworkInterfacePropClusterAdapterID
,[ref]$oAPI
,[string]$strResourceGroupTypeFilter
,[ref]$discoverCSVResources
,[ref]$discoverNonCSVResources
)
{
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$error.Clear()
Function Load-CimModules
{
$ErrorActionPreference = 'SilentlyContinue'
$error.Clear()
$CimModule = Get-Module CimCmdlets
if ($null -eq $CimModule)
{
Import-Module CimCmdlets
$error.Clear()
}
}</Script></Contents>
<Unicode>true</Unicode>
</File>
<File>
<Name>DiscoverClustering.vbs</Name>
<Contents><Script>'Copyright (c) Microsoft Corporation. All rights reserved.
Option Explicit
Const DefaultStringMaxSize = 256
Const ObjectNameStringMaxSize = 4000
Const GuidStringSize = 38
Const Win2016VersionPrefix = "10."
'===================================================
' Global Variables
'===================================================
Dim g_oUtil
Dim g_oClusterUtil
Dim ScriptParams
Call Main
'==========================================================================
' Main
'==========================================================================
Sub Main
Dim result
Dim IsArgs
result = StartInitialization(IsArgs)
If (False = result) Then
Exit Sub
End If
Call DiscoverInstances(IsArgs)
End Sub 'Main
Function GetIsGuidFlag(sOsVersion)
Dim IsGuid
IsGuid = False
On Error Resume Next
If (True = HasValue(sOsVersion)) Then
If (Len(sOsVersion) >= 3) Then
If (Win2016VersionPrefix = Left(sOsVersion,3)) Then
IsGuid = True
End If
End If
End If
GetIsGuidFlag = IsGuid
End Function
Sub StartDiscovery(DiscoveryType,sOsVersion)
Dim IsGuid
Dim result
Dim message
On Error Resume Next
If (Exit_IncrementalDiscovery = DiscoveryType) Then
ScriptParams.oDiscoveryData.IsSnapshot = False
Else
If (Start_SnapShotDiscovery = DiscoveryType) Then
IsGuid = GetIsGuidFlag(sOsVersion)
result = ScriptParams.DiscoverWindowsCluster(IsGuid)
If (False = result) Then
Call ScriptParams.ThrowEmptyDiscoveryData(False)
message = "There is error during discovery cluster objects."
message = GetErrorMessage(message)
g_oUtil.LogMessage g_oUtil.DBG_ERROR, message
Call g_oUtil.LogScomEvent(DiscoveryScriptName,ScriptEventId,EventTypeError,message)
End If
End If
End If
End Sub
Sub DiscoverInstances(ByVal IsArgs)
On Error Resume Next
g_oUtil.LogMessage g_oUtil.DBG_TRACE, "Started dicovery at machine local time: " & CStr(Time)
Dim message
Dim result
Dim DiscoveryType
Dim sOsVersion
Dim IsCluster
result = ScriptParams.InitDiscovery()
If (false = result) Then
Exit Sub
End If
If (False = IsArgs) Then
ScriptParams.oDiscoveryData.IsSnapshot = False
Call ScriptParams.PostDiscoveryData()
Exit Sub
End If
WScript.Echo ""
g_oUtil.LogMessage g_oUtil.DBG_TRACE, "Finished dicovery at machine local time: " & CStr(Time)
On Error Goto 0
End Sub
'===================================================
' Global Initialization
'===================================================
Function StartInitialization(ByRef IsArgs)
On Error Resume Next
Dim message
StartInitialization = False
IsArgs = False
Set g_oUtil = New Util
If (0<>Err.number) Then
message = "Failed to initialize engine."
message = GetErrorMessage(message)
WScript.Echo message
Exit Function
End If
Set g_oClusterUtil = new ClusterUtil
If (0<>Err.number) Then
message = "Failed to initialize cluster helper engine."
message = GetErrorMessage(message)
WScript.Echo message
Exit Function
End If
Set ScriptParams = New ScriptParameters
If (0<>Err.number) Then
message = "Failed to initialize script helper engine."
message = GetErrorMessage(message)
WScript.Echo message
Exit Function
End If
Call g_oUtil.SetDebugLevel(g_oUtil.DBG_NONE)
If (0<>Err.number) Then
message = "Failed to initialize debug level."
message = GetErrorMessage(message)
WScript.Echo message
Exit Function
End If
Dim result
result = ScriptParams.Initialize(IsArgs)
StartInitialization = result
On Error Goto 0
End Function
'==========================================================================
' Class: ClusterUtil
' Description: Utility methods for clustering
'==========================================================================
Class ClusterUtil
'**********************************************************************
Public Function EscapeString(ByVal sText)
Const METACHARACTERS = """\"
Dim sResult
Dim i
For i = 1 To Len(sText)
Dim sCurrentChar
sCurrentChar = Mid(sText, i, 1)
If InStr(METACHARACTERS, sCurrentChar) <> 0 Then
sResult = sResult & "\"
End If
sResult = sResult & sCurrentChar
Next
g_oUtil.LogMessage _
g_oUtil.DBG_TRACE, _
"ESCAPEd string: " & sResult
EscapeString = sResult
End Function
'**********************************************************************
Function WMIExecQueryNoAbort(ByVal sNamespace, ByVal sQuery)
Dim oWMI, oQuery, nInstanceCount, message
Set WMIExecQueryNoAbort = Nothing
On Error Resume Next
Set oWMI = GetObject(sNamespace)
If ((False = HasValue(oWMI)) Or (0 <> Err.number)) Then
message = "Unable to open WMI Namespace '" & sNamespace & "'. Check to see if the WMI service is enabled and running, and ensure this WMI namespace exists."
message = GetErrorMessage(message)
Call g_oUtil.LogScomEvent(DiscoveryScriptName,ScriptEventId,EventTypeError,message)
Exit Function
End If
Set oQuery = oWMI.ExecQuery(sQuery)
If ((False = HasValue(oQuery)) Or (0 <> Err.number)) Then
message = "The Query '" & sQuery & "' returned an invalid result set. Please check to see if this is a valid WMI Query."
Call g_oUtil.LogScomEvent(DiscoveryScriptName,ScriptEventId,EventTypeError,message)
Exit Function
End If
'Determine if we queried a valid WMI class - Count will return 0 or empty
nInstanceCount = oQuery.Count
If (0 <> Err.number) Then
message = "The Query '" & sQuery & "' did not return any valid instances. Please check to see if this is a valid WMI Query."
'Call g_oUtil.LogScomEvent(DiscoveryScriptName,ScriptEventId,EventTypeError,message)
Exit Function
End If
Set WMIExecQueryNoAbort = oQuery
End Function
'**********************************************************************
Function WMIGetInstances(ByVal sNamespace, ByVal sInstance)
Dim oWMI, oInstance, nInstanceCount, message
Set WMIGetInstances = Nothing
On Error Resume Next
Set oWMI = GetObject(sNamespace)
If ((False = HasValue(oWMI)) Or (0 <> Err.number)) Then
message = "Unable to open WMI Namespace '" & sNamespace & "'. Check to see if the WMI service is enabled and running, and ensure this WMI namespace exists."
Call g_oUtil.LogScomEvent(DiscoveryScriptName,ScriptEventId,EventTypeError,message)
Exit Function
End If
Set oInstance = oWMI.InstancesOf(sInstance)
If ((False = HasValue(oInstance)) Or (0 <> Err.number)) Then
message = "The class name '" & sInstance & "' returned no instances. Please check to see if this is a valid WMI class name."
Call g_oUtil.LogScomEvent(DiscoveryScriptName,ScriptEventId,EventTypeError,message)
Exit Function
End If
'Determine if we queried a valid WMI class - Count will return 0 or empty
nInstanceCount = oInstance.Count
If (0 <> Err.number) Then
message = "The class name '" & sInstance & "' did not return any valid instances. Please check to see if this is a valid WMI class name."
'Call g_oUtil.LogScomEvent(DiscoveryScriptName,ScriptEventId,EventTypeError,message)
Else
Set WMIGetInstances = oInstance
End If
End Function
'**********************************************************************
Function WMIGetInstance(ByVal sNamespace, ByVal sInstancePath)
Dim oWMI, oInstance, nInstanceCount
Dim message
Set WMIGetInstance = Nothing
On Error Resume Next
Set oWMI = GetObject(sNamespace)
If ((False = HasValue(oWMI)) Or (0 <> Err.number)) Then
message = "Unable to open WMI Namespace '" & sNamespace & "'. Check to see if the WMI service is enabled and running, and ensure this WMI namespace exists."
Call g_oUtil.LogScomEvent(DiscoveryScriptName,ScriptEventId,EventTypeError,message)
Exit Function
End If
Set oInstance = oWMI.Get(sInstancePath)
If ((True = IsNull(oInstance)) Or (0 <> Err.number)) Then
message = "The class name '" & sInstancePath & "' returned no instances. Please check to see if this is a valid WMI class name."
'Call g_oUtil.LogScomEvent(DiscoveryScriptName,ScriptEventId,EventTypeError,message)
Else
Set WMIGetInstance = oInstance
End If
End Function
Public Function GetNodeToActiveGroup(ClusterNameSpace,ByRef IsError)
On Error Resume Next
IsError = False
Set GetNodeToActiveGroup = Nothing
Dim oNodeToGroupDict
Dim oActiveNodes
Dim Query
Dim oService
Dim Count
Dim oActiveNode
Dim oGroup, oNode
Query = "select * from MSCluster_NodeToActiveGroup"
Set oNodeToGroupDict = CreateObject("Scripting.Dictionary")
If (0 <> Err.number) Then
Set oNodeToGroupDict = Nothing
IsError = True
Exit Function
End If
Set oService = GetObject(ClusterNameSpace)
If (0 <> Err.number) Then
Set oNodeToGroupDict = Nothing
Set oService = Nothing
IsError = True
Exit Function
End If
Set oActiveNodes = oService.ExecQuery(Query)
If (0 <> Err.number) Then
Set oNodeToGroupDict = Nothing
Set oService = Nothing
Set oActiveNodes = Nothing
IsError = True
Exit Function
End If
Count = oActiveNodes.Count
If (0 <> Err.number) Then
Set oNodeToGroupDict = Nothing
Set oService = Nothing
Set oActiveNodes = Nothing
IsError = True
Exit Function
End If
For Each oActiveNode in oActiveNodes
Set oGroup = oService.Get(oActiveNode.PartComponent)
Set oNode = oService.Get(oActiveNode.GroupComponent)
If (0 <> Err.number) Then
IsError = True
Exit For
End If
If (False = oNodeToGroupDict.Exists(oGroup.Name)) Then
Call oNodeToGroupDict.Add(oGroup.Name,oNode.Name)
If (0 <> Err.number) Then
IsError = True
Exit For
End If
End If
Next
Set oActiveNode = Nothing
Set oNode = Nothing
Set oGroup = Nothing
Set oService = Nothing
Set oActiveNodes = Nothing
Set GetNodeToActiveGroup = oNodeToGroupDict
End Function
Public Function GetResourceGroupType(oGroup)
GetResourceGroupType = Null
If (False = HasValue(oGroup)) Then
Exit Function
End if
On Error Resume Next
Dim GroupType,oGroupType
GroupType = oGroup.GroupType
If (0 = Err.Number) Then
GetResourceGroupType = GroupType
Exit Function
End If
Call Err.Clear()
Set oGroupType = oGroup.ExecMethod_("GetGroupType")
If (0 <> Err.Number) Then
' 2003 doesn't have method and property
If (WMI_INVALID_METHOD = Err.number) Then
Call Err.Clear()
End If
Exit Function
End if
GroupType = oGroupType.ReturnValue
If (0 = Err.Number) Then
GetResourceGroupType = GroupType
Else
Call Err.Clear()
End if
End Function
Public Function WMIGetIntegerProperty(oWmi, sPropName, defaultValue,ByRef IsError)
Dim result
Dim Value
Dim nCIMType
Dim Int32Value
Dim IsArray
result = 0
IsError = False
WMIGetIntegerProperty = result
If Not IsValidObject(oWmi) Then
Exit Function
End If
On Error Resume Next
Value = GetWmiVRawValueFromProperty(oWmi, sPropName, nCIMType, IsError,IsArray)
If (True = IsError) Then
Exit Function
End If
If IsNull(Value) Then
Exit Function
End If
If (wbemCimtypeUnknown = nCIMType) Then
Int32Value = CLng(Value)
If (0 = Err.Number) Then
result = Int32Value
Else
result = defaultValue
IsError = True
End If
Else
result = GetIntegerFromWmiProp(Value,nCIMType,defaultValue,IsArray)
End If
WMIGetIntegerProperty = result
On Error Goto 0
End Function
Public Function WMIGetStringProperty(oWmi, sPropName,ByRef IsError)
Dim result
Dim Value
Dim nCIMType
Dim sValue
Dim IsArray
result = ""
IsError = False
WMIGetStringProperty = result
If Not IsValidObject(oWmi) Then
Exit Function
End If
On Error Resume Next
Value = GetWmiVRawValueFromProperty(oWmi, sPropName, nCIMType, IsError,IsArray)
If (True = IsError) Then
Exit Function
End If
If IsNull(Value) Then
Exit Function
End If
If (wbemCimtypeUnknown = nCIMType) Then
sValue = CStr(Value)
If (0 = Err.Number) Then
result = sValue
Else
IsError = True
End If
Else
result = GetStringFromWmiProp(Value,nCIMType,IsArray)
End If
WMIGetStringProperty = result
On Error Goto 0
End Function
Private Function GetWmiVRawValueFromProperty(oWmi, sPropName,ByRef nCIMType,ByRef IsError,ByRef IsArray)
On Error Resume Next
Dim Value
Dim oWmiProp
Set oWmiProp = oWmi.Properties_.Item(sPropName)
If Err.Number <> 0 Then
IsError = True
Call Err.Clear()
Exit Function
End If
If (False = IsValidObject(oWmiProp)) Then
IsError = True
Exit Function
End If
Value = oWmiProp.Value
If Err.Number <> 0 Then
IsError = True
Call Err.Clear()
End If
nCIMType = oWmiProp.CIMType
If Err.Number <> 0 Then
nCIMType = wbemCimtypeUnknown
IsError = True
Call Err.Clear()
End If
IsArray = oWmiProp.IsArray
If Err.Number <> 0 Then
IsArray = False
IsError = True
End If
GetWmiVRawValueFromProperty = Value
On Error Goto 0
End Function
Private Function GetLargeInteger(iValue,defaultValue)
On Error Resume Next
Dim result
result = iValue
If ( iValue > Int32MaxValue) Then
result = defaultValue
ElseIf (iValue < Int32MinValue) Then
result = defaultValue
End If
GetLargeInteger = result
On Error Goto 0
End Function
Private Function GetIntegerFromDouble(Value,defaultValue)
On Error Resume Next
Dim result
result = Value
If ( Value > Int32MaxValue) Then
result = defaultValue
ElseIf (Value < Int32MinValue) Then
result = defaultValue
Else
result = CLng(Value)
End If
GetIntegerFromDouble = result
On Error Goto 0
End Function
Private Function GetStringFromDateTime(Value)
On Error Resume Next
Dim result
Dim sTmpStrDate,sValue
result = ""
sValue = CStr(Value)
If Err.number <> 0 Then
Exit Function
End If
result = sValue
' First attempt to convert the whole wmi date string
'
sTmpStrDate = Mid(sValue, 5, 2) & "/" & Mid(sValue, 7, 2) & "/" & Left(sValue, 4) & " " & Mid (sValue, 9, 2) & ":" & Mid(sValue, 11, 2) & ":" & Mid(sValue, 13, 2)
If ( IsDate(sTmpStrDate) )Then
result = sTmpStrDate
Else
' Second, attempt just to convert the YYYYMMDD
'
sTmpStrDate = Mid(sValue, 5, 2) & "/" & Mid(sValue, 7, 2) & "/" & Left(sValue, 4)
If IsDate(sTmpStrDate) Then
result = sTmpStrDate
End If
End If
GetStringFromDateTime = result
On Error Goto 0
End Function
Private Function GetIntegerFromWmiProp(Value,nCIMType,defaultValue,IsArray)
On Error Resume Next
Dim result
result = 0
Select Case (nCIMType)
Case wbemCimtypeSint16, wbemCimtypeSint8, wbemCimtypeUint8, wbemCimtypeUint16:
If (False = IsArray) Then
result = CLng(Value)
Else
result = CLng(Value(0))
End If
Case wbemCimtypeSint32,wbemCimtypeUint32, wbemCimtypeSint64, wbemCimtypeUint64:
If (False = IsArray) Then
result = GetLargeInteger(Value,defaultValue)
Else
result = GetLargeInteger(Value(0),defaultValue)
End If
Case wbemCimtypeReal32, wbemCimtypeReal64:
If (False = IsArray) Then
result = GetIntegerFromDouble(Value,defaultValue)
Else
result = GetIntegerFromDouble(Value(0),defaultValue)
End If
Case wbemCimtypeBoolean:
If (1= Value) Or (UCase(Value) = "TRUE") Then
result = 1
End If
End Select
GetIntegerFromWmiProp = result
On Error Goto 0
End Function
Private Function GetStringFromWmiProp(Value,nCIMType,IsArray)
On Error Resume Next
Dim result
result = ""
Select Case (nCIMType)
Case wbemCimtypeString,wbemCimtypeSint16, wbemCimtypeSint8, wbemCimtypeUint8, wbemCimtypeUint16,wbemCimtypeSint32,wbemCimtypeUint32, wbemCimtypeSint64, wbemCimtypeUint64,wbemCimtypeReal32, wbemCimtypeReal64:
If (False = IsArray) Then
result = CStr(Value)
Else
result = Join(Value, ", ")
End If
Case wbemCimtypeDatetime:
result = GetStringFromDateTime(Value)
Case wbemCimtypeBoolean:
If (1= Value) Or (UCase(Value) = "TRUE") Then
result = "true"
Else
result = "false"
End If
End Select
GetStringFromWmiProp = result
On Error Goto 0
End Function
'**********************************************************************
Public Function IsValidObject(ByVal oObject)
IsValidObject = False
If IsObject(oObject) Then
If Not oObject Is Nothing Then
IsValidObject = True
End If
End If
End Function
If (0 <> Err.Number)Then
Set oRelationshipInstance = Nothing
Exit Function
End If
Call oDiscoveryData.AddInstance(oRelationshipInstance)
result = (0 = Err.number)
Set oRelationshipInstance = Nothing
DiscoverClusterContainsRelationship = result
End Function
Private Function GetOsFilter(OSVersion,delimiter)
On Error Resume Next
Err.Clear
Dim Filter,Prefix,Separator,EndClause
Dim OsVersions,SubFilter
Filter = " where ProductType != 1"
GetOSFilter = Filter
If (Not HasValue(OSVersion) or 0 = Len(OSVersion)) Then
Exit Function
End If
If (Not HasValue(delimiter)) Then
delimiter = ","
End If
If (delimiter = OSVersion) Then
Exit Function
End If
Prefix = " and (Version like '"
Separator = "%' or Version like '"
EndClause = "%')"
OsVersions = Split(OSVersion,delimiter)
SubFilter = Join(OsVersions,Separator)
Filter = Filter & Prefix & SubFilter & EndClause
GetOSFilter = Filter
On Error Goto 0
End Function
Private Function GetServerOsVersionCheck(sComputerName,ByRef OsVersion,ByRef IsError)
On Error Resume Next
Err.Clear
Dim strQuery,oWmiSet, sWmiTarget, Count, Filter
Dim oObject,OsVer
IsError = False
GetServerOsVersionCheck = False
If ( IsObject(OsVersion)) Then
Exit Function
End If
sWmiTarget = "."
If ( Not IsObject(sComputerName)) Then
If (HasValue(sComputerName) and Len(sComputerName) > 0 ) Then
sWmiTarget = "" & sComputerName
End If
End If
sWmiTarget = "winmgmts:\\" & sWmiTarget & "\root\cimv2"
Filter = GetOsFilter(OsVersion,",")
StrQuery = "select Version from Win32_OperatingSystem" & Filter
Set oWmiSet = WMIExecQueryNoAbort(sWmiTarget, strQuery)
If Err.Number <> 0 Then
IsError = True
Exit Function
End If
Count = oWmiSet.Count
If Err.Number <> 0 Then
IsError = True
Exit Function
End If
OsVer = ""
For Each oObject in oWmiSet
OsVer = oObject.Version
If (0 = Err.Number) Then
OsVersion = OsVer
End If
Exit For
Next
GetServerOsVersionCheck = ( Count > 0)
On Error Goto 0
End Function
Public Function GetSnapshotDiscovery(ByRef OsVersion)
Dim bIsOsValid,bIsError,iResult
On Error Resume Next
If ( False = HasValue(OsVersion)) Then
iResult = Start_SnapShotDiscovery
GetSnapshotDiscovery = iResult
Exit Function
End If
If ( "" = OsVersion) Then
iResult = Start_SnapShotDiscovery
GetSnapshotDiscovery = iResult
Exit Function
End If
If (bIsOsValid) Then
iResult = Start_SnapShotDiscovery
Else
If (bIsError) Then
iResult = Exit_IncrementalDiscovery
Else
iResult = Exit_SnapShotDiscovery
End IF
End If
GetSnapshotDiscovery = iResult
End Function
'******************************************************************************
' FUNCTION: GetRegistryKeyValue
' DESCRIPTION: Returns the Registry Key Value
' RETURNS: Registry Key Value
'******************************************************************************
Public Function GetRegistryKeyValue(ByVal keyPath, ByVal key, ByRef IsError)
Dim oReg, strKeyValue
If (Err.Number <> 0) Then
IsError = True
Exit Function
End If
strKeyValue = oReg.RegRead(keyPath & key)
If Err.Number <> 0 Then
strKeyValue = ""
End If
GetRegistryKeyValue = strKeyValue
' resume error
On Error Goto 0
End Function
Public Function CheckWinClusterPresent()
Const ClusterNamePath = "HKLM\Cluster\"
Const ClusterNameValue = "ClusterName"
Dim IsCluster
Dim IsError
Dim result
On Error Resume Next
IsCluster = GetRegistryKeyValue(ClusterNamePath,ClusterNameValue,IsError)
result = (True = IsError) Or ( (False = IsError) and (Len(IsCluster) > 0 ) )
CheckWinClusterPresent = result
On Error Goto 0
End Function
End Class 'ClusterUtil
'===================================================
' Simple Common Functions
'===================================================
Function GetErrorMessage(message)
If ( 0 <> Len(Err.Description)) Then
message = message & " Error: Id: " & Err.number & " Description:" & Err.Description
End If
GetErrorMessage = message
End Function
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
Function GetDispObjectName(ObjectName,PostFix)
Dim pLen,oLen
Dim delta, delta1
Dim result
oLen = Len(ObjectName)
pLen = Len(PostFix)
delta1 = pLen - ObjectNameStringMaxSize
delta = delta1 + oLen
result = ObjectName & PostFix
If ( delta > 0) Then
If (delta1 >= 0) Then
result = Left(result,ObjectNameStringMaxSize)
Else
result = Left(ObjectName,-delta1) & PostFix
End If
End If
Class Error
Public Description
Public Number
Public Source
Sub Class_Initialize()
Number = 0
End Sub
Sub Save
Description = Err.Description
Number = Err.Number
Source = Err.Source
Err.Clear
End Sub
Sub Raise()
If (0 <> Number) Then
Call Err.Raise(Number, Source, Description)
End If
End Sub
Sub RaiseError(iNumber, sSource, sDescription)
If (0 <> iNumber) Then
Call Err.Raise(iNumber, sSource, sDescription)
End If
End Sub
End Class
'==========================================================================
' Class: Util
' Description: Utility methods for logging
'==========================================================================
Class Util
'==========================================================================
'Class Properties
' Used to say to LogMessage when/how to print the message.
'==========================================================================
Public DBG_NONE
Public DBG_ERROR
Public DBG_WARNING
Public DBG_TRACE
Public momAPI
'Internal Debug Level
Private m_nDebugLevel
Private m_Error
'==========================================================================
'Class Methods
' Used to say to LogMessage when/how to print the message.
'==========================================================================
Public Function CheckObject(oObject,message)
On Error Resume Next
CheckObject = True
If (False = HasValue(oObject) ) Then
CheckObject = False
message = GetErrorMessage(message)
LogMessage DBG_ERROR, message
Call LogScomEvent(DiscoveryScriptName,ScriptEventId,EventTypeError,message)
Call Err.Clear()
End If
End Function
'**********************************************************************
Public Function ThrowScriptErrorNoAbort(ByVal sMessage, ByVal oErr)
On Error Resume Next
LogMessage _
DBG_ERROR, _
sMessage & vbCrLf & oErr.Description
Call LogScomEvent (DiscoveryScriptName, ScriptEventId, EventTypeError, "Discovery script failed. Possible causes include Cluster Service or WMI Service not running. The error was: " & sMessage & " " & oErr.Description)
End Function
'**********************************************************************
Public Function ThrowScriptError(Byval sMessage, ByVal oErr)
On Error Resume Next
ThrowScriptErrorNoAbort sMessage, oErr
'switch to incremental discovery and return
'empty snapshot, preventing the script failure
'from triggering an alert
ThrowEmptyDiscoveryData(false)
Quit
End Function
Public Sub LogScomEvent(ScriptName,EventId,EventType,message)
If (False = HasValue(momAPI)) Then
Exit Sub
End If
Call m_Error.Save()
On Error Resume Next
Call momAPI.LogScriptEvent (ScriptName, EventId, EventType, message)
Call Err.Clear()
Call m_Error.Raise()
End Sub
Public Function GetStringProperty(sProperty,MaxSize)
GetStringProperty = ""
Dim Value
Dim MaxLength
If ( (False = HasValue(sProperty)) Or (True = IsObject(sProperty)) ) Then
Exit Function
End If
If ( (False = HasValue(MaxSize)) Or (True = IsObject(MaxSize)) ) Then
MaxLength = DefaultStringMaxSize
Else
MaxLength = MaxSize
End If
Call m_Error.Save()
On Error Resume Next
Value = CStr(sProperty)
If (0 <> Err.Number) Then
Value = ""
Call Err.Clear()
Else
If ( Len(Value) > MaxLength) Then
Value = Left(Value, MaxLength)
End If
End If
GetStringProperty = Value
Call m_Error.Raise()
End Function
Public Sub RaiseError(message)
On Error Resume Next
'======================================================================
' Method: GetCurrentLevel
' Description: retrieve current logging level.
' Parameters:
'======================================================================
Public Function GetCurrentLevel()
GetCurrentLevel = m_nDebugLevel
End Function
'======================================================================
' Method: SetDebugLevel
' Description: To change the debugging output level of information
' generated by this utility.
' Parameters:
' nLevel - DBG_NONE, DBG_TRACE, DBG_WARNING or DBG_ERROR
'======================================================================
Public Sub SetDebugLevel(ByVal nLevel)
m_nDebugLevel = nLevel
End Sub
'======================================================================
' Method: LogMessage
' Description: Log a debug message to ScriptContext
' Parameters:
' nLevel - Debug level for the message that
' we're logging.
' strMessage - The message to write to the trace.
'======================================================================
Public Sub LogMessage( _
ByVal nLevel, _
ByVal strMessage _
)
If (nLevel >= GetCurrentLevel()) Then
if (nLevel = DBG_ERROR) Then
WScript.Echo "[Error]: " & strMessage
ElseIf (nLevel = DBG_WARNING) Then
WScript.Echo "[Warning]: " & strMessage
ElseIf (nLevel = DBG_TRACE) Then
WScript.Echo "[Trace]: " & strMessage
End If
End If
End Sub
'======================================================================
' Method: Class_Initialize
' Description: This is the constructor
' Parameters:
'======================================================================
Private Sub Class_Initialize()
' Initialize Debug level constants
DBG_TRACE = 1
DBG_WARNING = 2
DBG_ERROR = 3
DBG_NONE = 4
'by default only errors are logged
m_nDebugLevel = DBG_ERROR
Set m_Error = New Error
End Sub
End Class ' Util
Class ScriptParameters
Public SourceId
Public ManagedEntityId
Public HealthServiceName
Public NetBiosName
Public discoverUnusedNetworks
Public networkContainsInterfaceGuid
Public networkInterfaceTypeGuid
Public networkInterfacePropClusterNameGuid
Public networkInterfacePropNameGuid
Public discoverCSVResources
Public discoverNonCSVResources
Public ResourceGroupDiscoveryLimit
Public appendClusterNameToResourceGroup
Public strNetworkInterfacePropClusterAdapterID
Public OsVersion
Public ObjResourceGroupTypeFilter
'======================================================================
' Method: Class_Initialize
' Description: This is the constructor
' Parameters:
'======================================================================
Private Sub Class_Initialize()
On Error Resume Next
Set oWShell = CreateObject("WScript.Shell")
If (0 <> Err.number) Then
Set oWShell = Nothing
End If
Public Function Initialize(ByRef IsArgs)
Dim oArgs
Dim message
On Error Resume Next
Initialize = False
IsArgs = False
Set oAPI = CreateObject("MOM.ScriptAPI")
If ((False = HasValue(oAPI )) Or (0 <> Err.number)) Then
message = " " & DiscoveryScriptName & " : Failed to get MOM API. MOM v3 must be installed to execute this script."
message = GetErrorMessage(message)
g_oUtil.LogMessage g_oUtil.DBG_ERROR, message
Call LogEventToWs(EventTypeError,message)
Exit Function
End If
If (True = HasValue(g_oUtil)) Then
Set g_oUtil.momAPI = oAPI
End If
Set oArgs = WScript.Arguments
If (0 <> Err.number) Then
Exit Function
End If
If oArgs.Count < 2 Then
message = "Wrong number of arguments: " & oArgs.Count & " instead of minimal 12."
g_oUtil.LogMessage g_oUtil.DBG_ERROR, message
If (True = HasValue(g_oUtil)) Then
Call g_oUtil.LogScomEvent(DiscoveryScriptName,ScriptEventId,EventTypeError,message)
End If
Exit Function
End If
SourceId = oArgs(0) ' this is always going to be same GUID to allow for multiple discoveries do updates at the same time
ManagedEntityId = oArgs(1)
If oArgs.Count >= 12 Then
IsArgs = True
Else
If ((True = HasValue(SourceId)) And (True = HasValue(ManagedEntityId)) ) Then
Initialize = True
End If
Exit Function
End If
If ( oArgs.Count < 13) Then
appendClusterNameToResourceGroup = false
Else
appendClusterNameToResourceGroup = ConvertToBoolean(oArgs(12))
End If
If ( oArgs.Count > 13 ) Then
strNetworkInterfacePropClusterAdapterID = oArgs(13)
End If
'Adding New Parameter for Resource Group Types Filter
If ( oArgs.Count > 14) Then
strResourceGroupTypeFilter = oArgs(14)
End If
If ( oArgs.Count > 15) Then
OsVersion = Replace(oArgs(15), Chr(34), "")
End If
Err.Clear
ObjResourceGroupTypeFilter = Split(strResourceGroupTypeFilter , ",")
If (0 <> Err.number) Then
Call Err.Clear()
ObjResourceGroupTypeFilter = DefaultClusterGroupTypes
End If
Initialize = CheckScriptParameters()
End Function
Public Function ConvertToBoolean(Value)
On Error Resume Next
ConvertToBoolean = False
If (False = HasValue(Value)) Then
Exit Function
End If
If ( (True = IsObject(Value)) Or (True = IsArray(Value)) ) Then
Exit Function
End If
Dim bResult
bResult = CBool(Value)
If (0 <> Err.number) Then
bResult = false
Call Err.Clear()
End If
ConvertToBoolean = bResult
On Error Goto 0
End Function
Public Function InitDiscovery
InitDiscovery = False
On Error Resume Next
Set oDiscoveryData = oAPI.CreateDiscoveryData (0,SourceId,ManagedEntityId)
If ( (False = HasValue(oDiscoveryData)) Or (0 <> Err.Number) ) Then
Set oDiscoveryData = Nothing
message = "Failed to get Discovery Data Object. MOM v3 must be installed to execute this script."
message = GetErrorMessage(message)
'==========================================================================
' FUNCTIONS
'==========================================================================
Sub ThrowEmptyDiscoveryData(IsSnapShot)
On Error Resume Next
If (False = HasValue(oAPI)) Then
Exit Sub
End If
Set oDiscoveryData = Nothing
Set oDiscoveryData = oAPI.CreateDiscoveryData(0, SourceId, ManagedEntityId)
If ((False = HasValue(oDiscoveryData)) Or (0 <> Err.Number)) Then
Call Err.Clear()
Exit Sub
End If
oDiscoveryData.IsSnapshot = IsSnapShot
On Error Goto 0
End Sub
Public Sub PostDiscoveryData()
On Error Resume Next
If (False = HasValue(oAPI)) Then
Exit Sub
End If
oAPI.Return(oDiscoveryData)
Set oDiscoveryData = Nothing
Set oAPI = Nothing
On Error Goto 0
End Sub
Public Sub LogEventToWs(EventType,message)
On Error Resume Next
If (False = HasValue(oWShell)) Then
Set oWShell = CreateObject("WScript.Shell")
If (0 <> Err.number) Then
Set oWShell = Nothing
On Error Goto 0
Exit Sub
End If
End If
Call oWShell.LogEvent(EventType,message)
On Error Goto 0
End Sub
Public Function DiscoverWindowsCluster(ByVal IsGuid)
Dim oWinCluster
Dim message
Dim result
DiscoverWindowsCluster = False
On Error Resume Next
message = "Failed to create cluster discovery helper objects."
Set oWinCluster = New WinCluster
result = g_oUtil.CheckObject(oWinCluster,message)
If (False = result) Then
Exit Function
End If
Set oWinCLuster = Nothing
DiscoverWindowsCluster = result
End Function
Private Function CheckScriptParameters()
CheckScriptParameters = False
On Error Resume Next
If ((False = HasValue(SourceId)) Or (False = HasValue(ManagedEntityId)) Or (False = HasValue(HealthServiceName)) Or (False = HasValue(NetBiosName)) ) Then
Exit Function
End If
If ((False = HasValue(networkContainsInterfaceGuid)) Or (False = HasValue(networkInterfaceTypeGuid)) Or (False = HasValue(networkInterfacePropClusterNameGuid)) Or (False = HasValue(networkInterfacePropClusterNameGuid)) ) Then
Exit Function
End If
If ( ( GuidStringSize > Len(Trim(SourceId))) Or (GuidStringSize > Len(Trim(ManagedEntityId))) ) Then
Exit Function
End If
If ( (GuidStringSize > Len(Trim(networkInterfaceTypeGuid))) Or (GuidStringSize > Len(Trim(networkInterfacePropClusterNameGuid))) Or (GuidStringSize > Len(Trim(networkInterfacePropClusterNameGuid))) ) Then
Exit Function
End If
If ( (0 = Len(Trim(HealthServiceName))) Or (0 = Len(Trim(NetBiosName))) Or (False = Len(Trim(networkContainsInterfaceGuid))) ) Then
Exit Function
End If
CheckScriptParameters = True
On Error Goto 0
End Function
End Class
'==========================================================================
' Class: WinCluster
' Description: holding cluster object and its properties
'==========================================================================
Class WinCluster
result = false
Discover = result
On Error Resume Next
Set oClusters = g_oClusterUtil.WMIGetInstances(ClusterNameSpace, "MSCluster_Cluster")
If (0 <> Err.number) Then
Set oClusters = Nothing
If ((WMI_INVALID_NAMESPACE = Err.number) Or (WMI_INVALID_CLASS = Err.number)) Then
Discover = True
End If
Exit Function
End If
result = true
For Each oCluster in oClusters
Dim ClusterName
ClusterName = oCluster.Name
If (0 <> Err.number) Then
result = false
Exit For
End If
result = DiscoverClusterInstance(ClusterName, oClusterInstance,oDiscoveryData)
If (False = result) Then
Exit For
End If
result = DiscoverNodes(oCluster,ClusterName,oClusterInstance,oDiscoveryData,ComputerName,NetBiosName)
If (False = result) Then
Exit For
End If
result = DiscoverNetworks(oCluster,ClusterName,oClusterInstance,oDiscoveryData,ComputerName,NetBiosName,NetworkInterfaceTypeGuid,NetworkContainsInterfaceGuid,discoverUnusedNetworks,false,networkInterfacePropClusterNameGuid,networkInterfacePropNameGuid,strNetworkInterfacePropClusterAdapterID,IsGuid)
If (False = result) Then
Exit For
End If
result = DiscoverGroups(oCluster,NetBiosName,ClusterName,oClusterInstance,oDiscoveryData,ComputerName,GroupTypeFilter,appendClusterNameToResourceGroupName,ResourceGroupDiscoveryLimit,discoverNonCSVResources,discoverCSVResources)
If (False = result) Then
Exit For
End If
Next
Set oClusterInstance = Nothing
Set oCluster = Nothing
Set oClusters = Nothing
Discover = result
End Function
Private Function DiscoverClusterInstance(ByVal ClusterName, ByRef oClusterInstance, ByRef oDiscoveryData)
On Error Resume Next
Dim result
result = false
DiscoverClusterInstance = result
Set oClusterInstance = Nothing
Set oClusterInstance = oDiscoveryData.CreateClassInstance("$MPElement[Name='Cluster!Microsoft.Windows.Cluster']$")
If ((False = HasValue(oClusterInstance)) Or (0 <> Err.number)) Then
Set oClusterInstance = Nothing
Exit Function
End If
Call oClusterInstance.AddProperty("$MPElement[Name='Cluster!Microsoft.Windows.Cluster']/Name$",ClusterName)
If (0 <> Err.number) Then
Set oClusterInstance = Nothing
Exit Function
End If
oDiscoveryData.AddInstance(oClusterInstance)
result = (0 = Err.number)
DiscoverClusterInstance = result
End Function
Private Function DiscoverNodes(oCluster,ClusterName,oClusterInstance,ByRef oDiscoveryData,ComputerName,NetBiosName)
' cluster node helpers
Dim oWinClusterNode
Dim oNodes
Dim result
Dim Count
Dim IsFound 'Flag for correct Node
result = False
DiscoverNodes = result
If (False = HasValue(oCluster)) Then
Exit Function
End If
On Error Resume Next
Set oWinClusterNode = new WinClusterNode
If ( (False = HasValue(oWinClusterNode)) Or (0 <> Err.Number) ) Then
Set oWinClusterNode = Nothing
Exit Function
End If
Set oNodes = oCluster.Associators_("MSCluster_ClusterToNode", "", "", "", False, False, "", "", 0)
If ( 0 <> Err.Number ) Then
Set oWinClusterNode = Nothing
Set oNodes = Nothing
Exit Function
End If
Count = oNodes.Count
If (0 <> Err.Number) Then
Set oWinClusterNode = Nothing
Set oNodes = Nothing
Exit Function
End If
If (0 = Count) Then
Set oWinClusterNode = Nothing
Set oNodes = Nothing
DiscoverNodes = True
Exit Function
End If
Dim oNode
result = true
IsFound = False
For Each oNode in oNodes
result = oWinClusterNode.DiscoverInstance (ClusterName, oNode,oDiscoveryData,ComputerName,NetBiosName,IsFound)
If (False = result) Then
Exit For
End If
If (True = IsFound) Then
result = oWinClusterNode.DiscoverClusterContainsRelationship(oClusterInstance, oDiscoveryData,ComputerName)
If (False = result) Then
Exit For
End If
End If
Next
Set oWinClusterNode = Nothing
Set oNode = Nothing
Set oNodes = Nothing
DiscoverNodes = result
End Function
Private Function DiscoverNetworks(oCluster,ClusterName,oClusterInstance,ByRef oDiscoveryData,ComputerName,NetBiosName,NetworkInterfaceTypeGuid,NetworkContainsInterfaceGuid,discoverUnusedNetworks,appendClusterNameToResourceGroupName,networkInterfacePropClusterNameGuid,networkInterfacePropNameGuid,strNetworkInterfacePropClusterAdapterID,IsGuid)
Dim oNetworks
Dim result
Dim Count
result = False
DiscoverNetworks = result
If (False = HasValue(oCluster)) Then
Exit Function
End If
On Error Resume Next
Set oNetworks = oCluster.Associators_("MSCluster_ClusterToNetwork", "", "", "", False, False, "", "", 0)
If (0 <> Err.Number) Then
Set oNetworks = Nothing
Exit Function
End If
Count = oNetworks.Count
If (0 <> Err.Number) Then
Set oNetworks = Nothing
Exit Function
End If
If (0 = Count) Then
DiscoverNetworks = True
Set oNetworks = Nothing
Exit Function
End If
Dim oNetwork
Dim oWinClusterNetwork
Set oWinClusterNetwork = new WinClusterNetwork
If ( (False = HasValue(oWinClusterNetwork)) Or (0 <> Err.Number) ) Then
Set oNetworks = Nothing
Set oWinClusterNetwork = Nothing
Exit Function
End If
result = true
For Each oNetwork in oNetworks
' cluster network helpers
Dim discoverNetworkEnabled
result = oWinClusterNetwork.DiscoverInstance ( _
ClusterName _
,oNetwork _
,oDiscoveryData _
,ComputerName _
,ClusterNameSpace _
,NetBiosName _
,NetworkInterfaceTypeGuid _
,NetworkContainsInterfaceGuid _
,discoverUnusedNetworks _
,appendClusterNameToResourceGroupName _
,networkInterfacePropClusterNameGuid _
,networkInterfacePropNameGuid _
,strNetworkInterfacePropClusterAdapterID _
,discoverNetworkEnabled _
,IsGuid _
)
If (False = result) Then
Exit For
End If
If (True = discoverNetworkEnabled) Then
result = oWinClusterNetwork.DiscoverClusterContainsRelationship(oClusterInstance,ClusterName,oNetwork.Name,oDiscoveryData)
If (False = result) Then
Exit For
End If
End If
Next
Set oWinClusterNetwork = Nothing
Set oNetwork = Nothing
Set oNetworks = Nothing
DiscoverNetworks = result
End Function
'******************************************************************************
' FUNCTION: IndexOf
' DESCRIPTION: Returns Index of Search Element Value Inside an Array
' RETURNS: Index Number if not found return -1
'******************************************************************************
Private Function IndexOf(ByVal ObjArr, ByVal strToMatch)
'Default to an error code
IndexOf = -1
'Make sure an array was passed
If Not IsArray(ObjArr) Then Exit Function
'Check for matching index
Dim itmElem
For itmElem = 0 To UBound(ObjArr)
If StrComp(strToMatch, ObjArr(itmElem), vbTextCompare) = 0 Then
IndexOf = itmElem
Exit For
End If
Next
End Function
Private Function GetDiscoveryGroupFlag(GroupType,GroupTypeFilter)
GetDiscoveryGroupFlag = True
If (True = IsNull(GroupType)) Then
Exit Function
End If
If IndexOf(GroupTypeFilter,GroupType) <> -1 Then
GetDiscoveryGroupFlag = False
End If
End Function
Private Function DiscoverGroup( _
oWinClusterGroup _
,ComputerName _
,NetBiosName _
,ClusterName _
,oClusterInstance _
,oRealGroup _
,ByRef oDiscoveryData _
,GroupType _
,appendClusterNameToResourceGroupName _
,ActiveNodesDict _
,discoverNonCSVResources _
,discoverCSVResources _
)
Dim autoFailbackType
Dim description
Dim failbackWindowEnd
Dim failbackWindowStart
Dim failoverPeriod
Dim failoverThreshold
Dim persistentState
Dim result
Dim IsError
Dim defaultValue
Dim RealGroupName
defaultValue = -1
result = false
DiscoverGroup = result
If ( 0 <> Err.Number ) Then
Set oWinClusterGroup = Nothing
Set oGroups = Nothing
Exit Function
End If
Count = oGroups.Count
If ( 0 <> Err.Number ) Then
Set oWinClusterGroup = Nothing
Set oGroups = Nothing
Exit Function
End If
If ( 0 = Count ) Then
Set oWinClusterGroup = Nothing
Set oGroups = Nothing
InitiDiscoveryGroups = True
Exit Function
End If
Set ActiveNodesDict = g_oClusterUtil.GetNodeToActiveGroup(ClusterNameSpace, IsError)
If ((True = IsError) Or (False = HasValue(ActiveNodesDict)) ) Then
Set winClusterGroup = Nothing
Set oGroups = Nothing
Set ActiveNodesDict = Nothing
Exit Function
End If
InitDiscoveryGroups = True
End Function
Private Function DiscoverGroups(oCluster,NetBiosName,ClusterName,oClusterInstance,ByRef oDiscoveryData,ComputerName,GroupTypeFilter,appendClusterNameToResourceGroupName,ResourceGroupDiscoveryLimit,discoverNonCSVResources,discoverCSVResources)
Dim oWinClusterGroup,oGroups,Count
Dim result
result = InitDiscoveryGroups(oCluster,oWinClusterGroup,oGroups, Count)
DiscoverGroups = result
If (False = result) Then
Exit Function
End If
On Error Resume Next
If ( 0 = Count ) Then
DiscoverGroups = True
Exit Function
End If
Dim oGroup
Dim iGroupCounter
Dim boolDiscoverGroup
Dim GroupType
Dim message
If (True = boolDiscoverGroup) Then
'Getting Discovered Group Index for comparing it with defined Discovery Limit
iGroupCounter = iGroupCounter + 1
' resource group discover limit exceeded?
If iGroupCounter > ResourceGroupDiscoveryLimit then
message = "" & ComputerName & " hosts " & iGroupCounter & " cluster resource groups which exceeds the configured threshold of " & ResourceGroupDiscoveryLimit & "."
Call g_oUtil.LogScomEvent(DiscoveryScriptName,GroupEventId,EventTypeWarning,message)
Exit For
Else
' no
' proceed with normal discovery
result = DiscoverGroup( _
oWinClusterGroup _
,ComputerName _
,NetBiosName _
,ClusterName _
,oClusterInstance _
,oGroup _
,oDiscoveryData _
,GroupType _
,appendClusterNameToResourceGroupName _
,ActiveNodesDict _
,discoverNonCSVResources _
,discoverCSVResources _
)
If (False = result) Then
Exit For
End If
End If
End if
Next
Set oGroup = Nothing
Set oWinClusterGroup = Nothing
Set oGroups = Nothing
Set ActiveNodesDict = Nothing
DiscoverGroups = result
End Function
End Class ' WinCluster
'==========================================================================
' Class: WinClusterNode
' Description: holding cluster node and its properties
'==========================================================================
Class WinClusterNode
'======================================================================
' only on same computer
'======================================================================
Dim NodeName
Dim description
Dim buildNumber
Dim cSDVersion
Dim majorVersion
Dim minorVersion
Dim nodeHighestVersion
Dim nodeLowestVersion
Dim IsError
Dim defaultValue
Dim result
Dim oInstance
result = false
DiscoverInstance = result
IsFound = False
If (False = HasValue(oObject) ) Then
Exit Function
End If
g_oUtil.LogMessage _
g_oUtil.DBG_TRACE, _
"Creating DiscoveryData packet for Microsoft.Windows.Cluster.Node."
Call Err.Clear()
Set oInstance = oDiscoveryData.CreateClassInstance( "$MPElement[Name='Microsoft.Windows.Cluster.Node']$")
If ( (False = HasValue(oInstance)) Or (0 <> Err.Number) ) Then
Exit Function
End If
'==========================================================================
' Class: WinClusterNetwork
' Description: holding cluster network and its properties
'==========================================================================
Class WinClusterNetwork
Private roleNone
'======================================================================
' Method: Class_Initialize
' Description: This is the constructor
' Parameters:
'======================================================================
Private Sub Class_Initialize()
roleNone = False
End Sub
Dim clusterHelper
Dim result
Dim IsError
Dim oInstance
Dim ObjectName
Dim address
Dim addressMask
Dim role
Dim description
Dim defaultValue
result = False
DiscoverInstance = result
If (False = HasValue(oObject) ) Then
Exit Function
End If
role = g_oClusterUtil.WMIGetIntegerProperty ( oObject, "Role", defaultValue, IsError )
If (True = IsError) Then
Exit Function
End If
roleNone = (0 = role)
If ( (False = discoverUnusedNetworks) and (True = roleNone) ) Then
discoverNetworkEnabled = False
DiscoverInstance = True
Exit Function
Else
discoverNetworkEnabled = True
End If
On Error Resume Next
Set clusterHelper = new WinClusterObject
If ( (0 <> Err.Number) Or (False = HasValue(clusterHelper)) ) Then
Set ClusterHelper = Nothing
Exit Function
End If
Dim result
Dim oNetworkItfs
Dim oNetworkItf
Dim oWinClusterNetworkInterface
Dim baseOSItfName
Dim NetIfSysName
Dim Count
Dim IsFound
Dim AdapterId
result = false
DiscoverNetItfs = result
If (False = HasValue(oObject) ) Then
Exit Function
End If
Set oNetworkItfs = oObject.Associators_("MSCluster_NetworkToNetworkInterface", "", "", "", False, False, "", "", 0)
If (0 <> Err.Number) Then
Set oNetworkItfs = Nothing
Exit Function
End If
Count = oNetworkItfs.Count
If (0 <> Err.Number) Then
Set oNetworkItfs = Nothing
Exit Function
End If
If (0 = Count) Then
DiscoverNetItfs = True
Set oNetworkItfs = Nothing
Exit Function
End If
Set oWinClusterNetworkInterface = new WinClusterNetworkInterface
If ( (0 <> Err.Number) Or (False = HasValue(oWinClusterNetworkInterface)) ) Then
Set oWinClusterNetworkInterface = Nothing
Set oNetworkItfs = Nothing
Exit Function
End If
result = true
IsFound = False
For Each oNetworkItf in oNetworkItfs
AdapterId = ""
baseOSItfName = GetNetIfName(oNetworkItf,NetIfSysName,AdapterId)
g_oUtil.LogMessage g_oUtil.DBG_TRACE, "Network: " & NetName & " interface: " & baseOSItfName
If (0 <> Len(Trim(baseOSItfName)) and (LCase(NetIfSysName) = LCase(NetBiosName)) ) Then
result = oWinClusterNetworkInterface.Initialize ( baseOSItfName,AdapterId, discoverUnusedNetworks, IsGuid )
If (False = result) Then
Exit For
End If
result = oWinClusterNetworkInterface.DiscoverInstance ( _
hostKey _
,baseOSItfName _
,oNetworkItf _
,oDiscoveryData _
,ComputerName _
,NetworkInterfaceTypeGuid _
,networkInterfacePropClusterNameGuid _
,networkInterfacePropNameGuid _
,strNetworkInterfacePropClusterAdapterID _
,IsFound _
)
If (False = result) Then
Exit For
End If
If (True = IsFound) Then
' discover that network contains interfaces
result = DiscoverContainsNetworkInterfacesRelationship ( _
hostKey _
,NetName _
,oWinClusterNetworkInterface.deviceID _
,NetIfSysName _
,oDiscoveryData _
,ComputerName _
,NetBiosName _
,NetworkInterfaceTypeGuid _
,NetworkContainsInterfaceGuid _
)
If (False = result) Then
Exit For
End If
End If
End If
Next
Set oNetworkItf = Nothing
Set oNetworkItfs = Nothing
result = false
DiscoverContainsNetworkInterfacesRelationship = result
On Error Resume Next
If ( 0 <> StrComp (LCase(NetBiosName) , LCase(NetIfSysName)) ) Then
DiscoverContainsNetworkInterfacesRelationship = True
Exit Function
End If
Call Err.Clear()
Dim oNetworkInstance
Set oNetworkInstance = oDiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Cluster.Network']$")
If ( (False = HasValue(oNetworkInstance)) Or (0 <> Err.number)) Then
Set oNetworkInstance = Nothing
Exit Function
End If
TrimKey = Trim(networkKey)
networkKey = g_oUtil.GetStringProperty(TrimKey,ObjectNameStringMaxSize)
With oNetworkInstance
If (0 <> Err.number) Then
Set oNetworkInstance = Nothing
Exit Function
End If
Dim oInstance
Set oInstance = oDiscoveryData.CreateClassInstance(NetworkInterfaceTypeGuid)
If ( (False = HasValue(oInstance)) Or (0 <> Err.number)) Then
Set oInstance = Nothing
Exit Function
End If
If (0 <> Err.number) Then
Set oInstance = Nothing
Exit Function
End If
Dim oRelationshipInstance
Set oRelationshipInstance = oDiscoveryData.CreateRelationshipInstance(NetworkContainsInterfaceGuid)
If ( (False = HasValue(oRelationshipInstance)) Or (0 <> Err.number)) Then
Exit Function
End If
Call oDiscoveryData.AddInstance(oRelationshipInstance)
result = (0 = Err.number)
Set oRelationshipInstance = Nothing
Set oInstance = Nothing
Set oNetworkInstance = Nothing
DiscoverContainsNetworkInterfacesRelationship = result
End Function
Dim oInstance
Call Err.Clear()
Set oInstance = oDiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Cluster.Network']$")
If ( (False = HasValue(oInstance)) Or (0 <> Err.number)) Then
Set oInstance = Nothing
Exit Function
End If
Set oInstance = Nothing
DiscoverClusterContainsRelationship = result
End Function
'============================================================
'Get Network Name from DeviceId
'OS < 2008
'DeviceId=NetName - SystemName
'OS >= 2008
' DeviceId=SystemName - NetName
'===========================================================
Private Function GetNetIfName(oNetworkItf,ByRef NetIfSysName,ByRef AdapterId)
On Error Resume Next
Dim systemName
Dim deviceId
Dim result
Dim lp,rp
Dim sysLen,dLen,delta
Dim IsError
Dim NicId
'======================================================================
' Method: Initialize
' Description: This is the constructor
' Parameters:
' NetworkName: NetConnectionId for Win 2003, AdapterId - 2008 and Higher
'======================================================================
Public Function Initialize(ByVal NetworkName,ByVal AdapterId ,ByVal discoverUnusedNetworks,ByVal IsGuid)
Dim sFilter
Dim IsError
Dim result
Dim message
Dim deviceIdp
Dim Count
Dim NicGuid
result = false
Initialize = result
Call Clear()
sFilter = GetQueryFilter(NetworkName,AdapterId,discoverUnusedNetworks)
If (0 = Len(sFilter)) Then
Initialize = True
Exit Function
End If
'Starting only on Cluster Node Instance so using "." as ComputerName
Dim WMISet, owObj
On Error Resume Next
Set WMISet = g_oClusterUtil.WMIGetInstances(NameSpace, sFilter)
If ( (0 <> Err.Number) Or (False = HasValue(WMISet)) ) Then
Set WMISet = Nothing
Exit Function
End If
Count = WMISet.Count
If (0 <> Err.Number) Then
Set WMISet = Nothing
Exit Function
End If
DeviceIdp = "DeviceId"
If (True = HasValue(IsGuid) and (True = IsGuid)) Then
DeviceIdp = "GUID"
End If
'If result set is empty because some Core Has empty Guid
If (0 = Count) Then
IsError = False
Set WMISet = Nothing
If (Len(AdapterId) <= 2) Then
Initialize = True
Exit Function
End If
Set WMISet = GetNicForCore(AdapterId, discoverUnusedNetworks, IsError)
If (False = IsError) Then
If (False = HasValue(WMISet)) Then
Initialize = True
Exit Function
End If
Else
Initialize = False
Exit Function
End If
End If
Dim result
Dim adapter
Dim address
Dim name
Dim strClusterAdapterID
Dim oInstance
Dim IsError
result = false
DiscoverInstance = result
IsFound = False
If (0 = Len(deviceID)) Then
DiscoverInstance = True
Exit Function
End If
g_oUtil.LogMessage _
g_oUtil.DBG_TRACE, _
"Creating DiscoveryData packet for " & networkInterfaceTypeGuid
Set oInstance = oDiscoveryData.CreateClassInstance(networkInterfaceTypeGuid)
If ( (0 <> Err.Number) Or (False = HasValue(oInstance)) ) Then
Exit Function
End If
If (Len(strClusterAdapterID) > 0 and Len(strNetworkInterfacePropClusterAdapterID) > 0) Then
.AddProperty _
strNetworkInterfacePropClusterAdapterID, strClusterAdapterID
End If
End With
If (0 <> Err.number) Then
Exit Function
End If
Call oDiscoveryData.AddInstance(oInstance)
result = (0 = Err.number)
IsFound = True
DiscoverInstance = result
End Function
Private Function GetAdapterId(oObject)
GetAdapterId = ""
If (False = HasValue(oObject)) Then
Exit Function
End If
Dim AdapterId
On Error Resume Next
Err.Clear
AdapterId = oObject.AdapterId
If (0 = Err.number) Then
AdapterId = Replace(AdapterId, "{", "")
AdapterId = Replace(AdapterId, "}", "")
GetAdapterId = AdapterId
End if
On Error Goto 0
End Function
Private Sub GetNicInfo(Index)
If (False = HasValue(Index)) Then
Exit Sub
End If
Dim sFilter,IsError
Dim WMISet, oObj
DIm Count
sFilter = "Win32_NetworkAdapterConfiguration where Index = " & Index
Set WMISet = g_oClusterUtil.WMIGetInstances(NameSpace, sFilter)
If ( (0 <> Err.Number) Or (False = HasValue(WMISet)) ) Then
Set WMISet = Nothing
Call Err.Clear()
Exit Sub
End If
On Error Resume Next
Count = WMISet.Count
If ( (0 <> Err.Number) Or (0 = Count) ) Then
Set WMISet = Nothing
Call Err.Clear()
Exit Sub
End If
'======================================================================
' Method: Class_Initialize
' Description: This is the constructor
' Parameters:
'======================================================================
Private Sub Class_Initialize()
NameSpace = "winmgmts:\\.\root\cimv2"
End Sub
Private Function GetQueryFilter(ByVal NetworkName,ByRef AdapterId,ByVal discoverUnusedNetworks)
On Error Resume Next
Dim sFilter
sFilter = ""
GetQueryFilter = sFilter
If ( (False = HasValue(NetworkName)) and (False = HasValue(AdapterId)) ) Then
'Nothing to find
Exit Function
End If
AdapterId = Trim(AdapterId)
If ( (0 = Len(NetworkName)) and (0 = Len(AdapterId)) ) Then
Exit Function
End If
If (0 = Len(AdapterId)) Then
NetworkName = Replace(NetworkName,"'","\'")
sFilter = "Win32_NetworkAdapter Where NetConnectionID = '" & NetworkName & "'"
Else
AdapterId = "{" & AdapterId & "}"
sFilter = "Win32_NetworkAdapter Where GUID = '" & AdapterId & "'"
End If
If (False = discoverUnusedNetworks) Then
sFilter = sFilter & " And NetConnectionStatus <> 0"
End If
GetQueryFilter = sFilter
On Error Goto 0
End Function
Private Function GetNicById(ByVal AdapterId,ByRef DevId)
On Error Resume Next
Dim sFilter
Dim WmiSet
Dim result
Dim Count
Dim NicCfg
Dim NicId
Dim IsError
DevId = ""
result = False
GetNicById = result
sFilter = "Win32_NetworkAdapterConfiguration where SettingID ='" & AdapterId & "'"
Set WmiSet = g_oClusterUtil.WMIGetInstances(NameSpace, sFilter)
If ( (0 <> Err.Number) Or (False = HasValue(WmiSet)) ) Then
Set WmiSet = Nothing
Exit Function
End If
Count = WMISet.Count
If (0 <> Err.Number) Then
Set WmiSet = Nothing
Exit Function
End If
If (0 = Count) Then
GetNicById = True
Exit Function
End If
NicId = ""
For Each NicCfg in WmiSet
NicId = g_oClusterUtil.WMIGetStringProperty(NicCfg, "Index" , IsError )
Exit For
Next
DevId = NicId
Set NicCfg = Nothing
Set WmiSet = Nothing
GetNicById = True
On Error Goto 0
End Function
Private Function GetNicByIndex(ByVal Index,ByVal discoverUnusedNetworks,ByRef IsError)
On Error Resume Next
Dim sFilter
Dim WmiSet
Dim Count
IsError = False
Set GetNicByIndex = Nothing
sFilter = "Win32_NetworkAdapter where Index = " & Index
If (False = discoverUnusedNetworks) Then
sFilter = sFilter & " And NetConnectionStatus <> 0"
End If
Set WmiSet = g_oClusterUtil.WMIGetInstances(NameSpace, sFilter)
If ( (0 <> Err.Number) Or (False = HasValue(WmiSet)) ) Then
IsError = True
Set WmiSet = Nothing
Exit Function
End If
Count = WMISet.Count
If (0 <> Err.Number) Then
IsError = True
Set WmiSet = Nothing
Exit Function
End If
If (0 <> Count) Then
Set GetNicByIndex = WmiSet
End If
Set WmiSet = Nothing
On Error Goto 0
End Function
Private Function GetNicForCore( ByVal AdapterId, ByVal discoverUnusedNetworks,ByRef IsError)
On Error Resume Next
Dim Index
Dim result
Index = ""
IsError = False
Set GetNicForCore = Nothing
result = GetNicById(AdapterId,Index)
If (False = result) Then
IsError = True
Exit Function
End If
If (0 = Len(Index) ) Then
Exit Function
End If
Set GetNicForCore = GetNicByIndex(Index,discoverUnusedNetworks,IsError)
On Error Goto 0
End Function
End Class ' WinClusterNetworkInterface
'==========================================================================
' Class: WinClusterObject
' Description: base holding object and its properties
'==========================================================================
Class WinClusterObject
g_oUtil.LogMessage _
g_oUtil.DBG_TRACE, _
"Creating DiscoveryData packet for " & discoveryClass & "."
Call Err.Clear()
Dim oInstance
Dim PostFix
Set DiscoverInstance = Nothing
Set oInstance = oDiscoveryData.CreateClassInstance(discoveryClass)
If ((False = HasValue(oInstance)) Or (0 <> Err.number)) Then
Set oInstance = Nothing
Exit Function
End If
Dim sObjectName,TrimName
Dim DispName
If ((discoveryClass = "$MPElement[Name='Microsoft.Windows.Cluster.Group']$") And (appendClusterNameToResourceGroupName = True)) Then
PostFix = " (" & hostKey & ")"
DispName = GetDispObjectName(ObjectName,PostFix)
Else
DispName = g_oUtil.GetStringProperty(ObjectName,ObjectNameStringMaxSize)
End If
TrimName = Trim(ObjectName)
If (0 = Len(TrimName)) Then
Exit Function
End If
If (0 <> Err.number) Then
Exit Function
End If
Set DiscoverInstance = oInstance
End Function
End Class ' WinClusterObject
'========='==========================================================================
' Class: WinClusterGroup
' Description: holding group object and its properties
'==========================================================================
Class WinClusterGroup
' instance
Dim result
Dim clusterHelper
Dim NodeName
result = False
DiscoverInstance = result
On Error Resume Next
Err.Clear
NodeName = ActiveNodesDict.Item(RealGroupName)
If (False = HasValue(NodeName)) Then
NodeName = NetBiosName
Else
If (0 = Len(NodeName)) Then
NodeName = NetBiosName
End If
End If
Set clusterHelper = new WinClusterObject
If ( (False = HasValue(clusterHelper)) Or (0 <> Err.Number) ) Then
Set ClusterHelper = Nothing
Exit Function
End If
Dim oInstance
Set oInstance = clusterHelper.DiscoverInstance ( _
hostKey, _
RealGroupName, _
"$MPElement[Name='Microsoft.Windows.Cluster.Group']$", _
oDiscoveryData, _
appendClusterNameToResourceGroupName _
)
If ( (False = HasValue(oInstance)) Or (0 <> Err.Number) ) Then
Set oInstance = Nothing
Set ClusterHelper = Nothing
Exit Function
End If
If (True = discoverNonCSVResources) Then
result = DiscoveryResources(hostkey,GroupName,oGroup,discoverNonCSVResources,oDiscoveryData,ComputerName,NetBiosName)
If (False = result) Then
DiscoverAllResources = result
Exit Function
End If
End If
If (True = discoverCSVResources) Then
result = DiscoveryCSVResources(hostkey,GroupName,GroupType,discoverCSVResources,oDiscoveryData,ComputerName,NetBiosName,ClusterNameSpace)
End If
DiscoverAllResources = result
End Function
Private Function DiscoveryResources( _
ByVal hostkey _
,ByVal GroupName _
,ByVal oGroup _
,ByVal discoverNonCSVResources _
,ByVal oDiscoveryData _
,ByVal ComputerName _
,ByVal NetBiosName _
)
On Error Resume Next
Dim result
result = False
DiscoveryResources = result
Dim oResources
Dim Query
Dim oResource
Dim oRealResource
Dim oWinClusterResource
Dim Count
GroupName = Trim(GroupName)
If (0 = Len(GroupName) ) Then
Exit Function
End If
Set oWinClusterResource = new WinClusterResource
If (0 <> Err.number) Then
Set oWinClusterResource = Nothing
Exit Function
End If
Set oResource = Nothing
Set oResources = Nothing
Set oWinClusterResource = Nothing
DiscoveryCSVResources = result
End Function
Private Function IsDiscoverCSVresource(GroupType,GroupName)
IsDiscoverCSVresource = False
If (True = IsNull(GroupType)) Then
If (LCase(GroupName) = "cluster group" ) Then
IsDiscoverCSVresource = True
End If
Else
If (1 = GroupType) Then
IsDiscoverCSVresource = True
End If
End If
On Error Resume Next
g_oUtil.LogMessage _
g_oUtil.DBG_TRACE, _
"Creating DiscoveryData packet for cluster contains groups."
Call Err.Clear()
Dim result
Dim sgroupKey
result = false
DiscoverClusterContainsRelationship = result
Dim oInstance
Set oInstance = oDiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Cluster.Group']$")
If ( (False = HasValue(oInstance)) Or (0 <> Err.Number) ) Then
Set oInstance = Nothing
Exit Function
End If
Dim result
Dim sGroupName
Dim DisplayName
Dim PostFix
Dim TrimGroupName
result = false
DiscoverInstanceForHosted = result
TrimGroupName = g_oUtil.GetStringProperty(Trim(GroupName),ObjectNameStringMaxSize)
sGroupName = g_oUtil.GetStringProperty(GroupName,ObjectNameStringMaxSize)
PostFix = " (" & hostKey & " )" & " (" & NetBiosName & ")"
DisplayName = GetDispObjectName(TrimGroupName,PostFix)
Dim oHostedGroupInstance
Set oHostedGroupInstance = oDiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']$" )
If ( (False = HasValue(oHostedGroupInstance)) Or (0 <> Err.Number) ) Then
Set oHostedGroupInstance = Nothing
Exit Function
End If
With oHostedGroupInstance
.AddProperty _
"$MPElement[Name='System!System.Entity']/DisplayName$", _
DisplayName
result = False
DiscoverClusterGroupContainsRelationship = result
g_oUtil.LogMessage _
g_oUtil.DBG_TRACE, _
"Creating DiscoveryData packet for cluster group contains hosted groups."
Call Err.Clear()
Dim oInstance
Set oInstance = oDiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Cluster.Group']$")
If ( (False = HasValue(oInstance)) Or (0 <> Err.Number) ) Then
Set oInstance = Nothing
Exit Function
End If
If ( 0 <> Err.Number ) Then
Set oInstance = Nothing
Exit Function
End If
Dim oHostedInstance
Set oHostedInstance = oDiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']$")
If ( (False = HasValue(oHostedInstance)) Or (0 <> Err.Number) ) Then
Set oInstance = Nothing
Set oHostedInstance = Nothing
Exit Function
End If
If (0 <> Err.Number ) Then
Set oInstance = Nothing
Set oHostedInstance = Nothing
Exit Function
End If
Dim oRelationshipInstance
Set oRelationshipInstance = oDiscoveryData.CreateRelationshipInstance("$MPElement[Name='Microsoft.Windows.Cluster.Group.Contains.Microsoft.Windows.Cluster.HostedGroup']$")
If ( (False = HasValue(oRelationshipInstance)) Or (0 <> Err.Number) ) Then
Set oInstance = Nothing
Set oHostedInstance = Nothing
Set oRelationshipInstance = Nothing
Exit Function
End If
If (0 <> Err.Number ) Then
Set oInstance = Nothing
Set oHostedInstance = Nothing
Set oRelationshipInstance = Nothing
Exit Function
End If
Call oDiscoveryData.AddInstance(oRelationshipInstance)
result = (0 = Err.number)
Set oInstance = Nothing
Set oHostedInstance = Nothing
Set oRelationshipInstance = Nothing
DiscoverClusterGroupContainsRelationship = result
End Function
End Class ' WinClusterGroup
'==========================================================================
' Class: WinClusterResource
' Description: holding cluster resource extension and its properties
'==========================================================================
Class WinClusterResource
'==========================================================================
' Discover instance
'==========================================================================
Public Function DiscoverInstance( _
ByVal clusterKey _
,ByVal groupKey _
,ByRef oObject _
,ByRef oDiscoveryData _
,ByVal ComputerName _
,ByVal NetBiosName _
)
On Error Resume Next
g_oUtil.LogMessage _
g_oUtil.DBG_TRACE, _
"Creating DiscoveryData packet for Microsoft.Windows.Cluster.Resource."
Dim ResourceName
Dim TrimResourceName
Dim lResourceName
Dim sgroupKey
Dim typeName
Dim description
Dim isAlivePollInterval
Dim LooksAlivePollInterval
Dim pendingTimeout
Dim persistentState
Dim restartAction
Dim restartPeriod
Dim restartThreshold
Dim retryPeriodOnFailure
Dim separateMonitor
Dim defaultValue
Dim IsError
Dim result
Dim DispName
Dim TrimName
result = false
DiscoverInstance = result
defaultValue = -1