Clusterdetectiescript (met bronfilter)

Microsoft.Windows.Cluster.Monitoring.Discovery.ScriptProbe.WithResourceFilter (ProbeActionModuleType)

Detectiescriptmodule voor Windows Server-cluster.

Element properties:

TypeProbeActionModuleType
IsolationAny
AccessibilityPublic
RunAsMicrosoft.Windows.Cluster.PrivilegedAccount
InputTypeSystem.BaseData
OutputTypeSystem.Discovery.Data

Member Modules:

ID Module Type TypeId RunAs 
Script ProbeAction Microsoft.Windows.PowerShellDiscoveryProbe Default

Overrideable Parameters:

IDParameterTypeSelectorDisplay NameDescription
DiscoverUnusedNetworksbool$Config/DiscoverUnusedNetworks$Ongebruikte netwerken detecteren
AppendClusterNameToResourceGroupNamebool$Config/AppendClusterNameToResourceGroupName$Clusternaam toevoegen aan brongroepnaam
DiscoverCSVResourcesbool$Config/DiscoverCSVResources$Bronnen van het gedeelde clustervolume detecteren
DiscoverNonCSVResourcesbool$Config/DiscoverNonCSVResources$Clusterbronnen detecteren
ResourceGroupDiscoveryLimitint$Config/ResourceGroupDiscoveryLimit$Detectielimiet van de brongroep
TimeoutSecondsint$Config/TimeoutSeconds$Time-out in seconden
ResourceGroupTypeFilterstring$Config/ResourceGroupTypeFilter$

Source Code:

<ProbeActionModuleType ID="Microsoft.Windows.Cluster.Monitoring.Discovery.ScriptProbe.WithResourceFilter" Accessibility="Public" RunAs="Cluster!Microsoft.Windows.Cluster.PrivilegedAccount" Batching="false" PassThrough="false">
<Configuration>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="TimeoutSeconds" type="xsd:integer"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="DiscoverySourceId" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="DiscoverUnusedNetworks" type="xsd:boolean"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="NetworkContainsInterfaceGuid" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="NetworkInterfaceTypeGuid" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="NetworkInterfacePropClusterNameGuid" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="NetworkInterfacePropNameGuid" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="DiscoverCSVResources" type="xsd:boolean"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="DiscoverNonCSVResources" type="xsd:boolean"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="ResourceGroupDiscoveryLimit" type="xsd:integer"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="0" name="AppendClusterNameToResourceGroupName" type="xsd:boolean"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="0" name="NetworkInterfacePropClusterAdapterID" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="0" name="ResourceGroupTypeFilter" type="xsd:string"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="DiscoverUnusedNetworks" Selector="$Config/DiscoverUnusedNetworks$" ParameterType="bool"/>
<OverrideableParameter ID="AppendClusterNameToResourceGroupName" Selector="$Config/AppendClusterNameToResourceGroupName$" ParameterType="bool"/>
<OverrideableParameter ID="DiscoverCSVResources" Selector="$Config/DiscoverCSVResources$" ParameterType="bool"/>
<OverrideableParameter ID="DiscoverNonCSVResources" Selector="$Config/DiscoverNonCSVResources$" ParameterType="bool"/>
<OverrideableParameter ID="ResourceGroupDiscoveryLimit" Selector="$Config/ResourceGroupDiscoveryLimit$" ParameterType="int"/>
<OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int"/>
<OverrideableParameter ID="ResourceGroupTypeFilter" Selector="$Config/ResourceGroupTypeFilter$" ParameterType="string"/>
</OverrideableParameters>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<ProbeAction ID="Script" TypeID="Windows!Microsoft.Windows.PowerShellDiscoveryProbe">
<ScriptName>DiscoverClustering.ps1</ScriptName>
<ScriptBody><Script>param($SourceId, $ManagedEntityId, $HealthServiceName, $NetBiosName, $discoverUnusedNetworks, $networkContainsInterfaceGuid, $networkInterfaceTypeGuid, $networkInterfacePropClusterNameGuid, $networkInterfacePropNameGuid, $discoverCSVResources, $discoverNonCSVResources, $ResourceGroupDiscoveryLimit, $appendClusterNameToResourceGroup, $strNetworkInterfacePropClusterAdapterID, $strResourceGroupTypeFilter)

#******************************************************************************
# FUNCTION: CheckByOSCurrentVersion
# DESCRIPTION: Returns True if the Registry Key for CurrentVersion
# is equal the target OS Versions Number.
# RETURNS: Boolean: True, if build is greater or equal than the given number
#******************************************************************************
function CheckByOSCurrentVersion()
{

$strCurrentOSVer = Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\"
$strCurrentOSVer = $strCurrentOSVer.CurrentVersion
$CheckByOSCurrentVersion = $false
switch ($strCurrentOSVer)
{
$WIN_SRV_2012_OSVer
{
$CheckByOSCurrentVersion = $true;
break;
}
$WIN_SRV_2012R2_OSVer{
$CheckByOSCurrentVersion = $true;
break;
}
default{
$CheckByOSCurrentVersion = $false;
}
}
return $CheckByOSCurrentVersion;
}

#******************************************************************************
# FUNCTION: CheckMinOSVer
# DESCRIPTION: Returns True if the Registry Key for CurrentVersion
# is equal or Higher than the Minimum OS Versions Number.
# PARAMETER: DblMinVer Minimum Version Number to use
# RETURNS: Boolean: True, if build is greater or equal than the given number
#******************************************************************************
function CheckMinOSVer($DblMinVer)
{
$strCurrentOSVer = Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\"
$strCurrentOSVer = $strCurrentOSVer.CurrentVersion
$DblCurrVer = [double]($strCurrentOSVer)
$CheckMinOSVer = $false
if($DblCurrVer -ge $DblMinVer){
$CheckMinOSVer = $true
}else{
$CheckMinOSVer = $false
}
return $CheckMinOSVer
}

#==========================================================================
# FUNCTIONS
#==========================================================================
function ThrowEmptyDiscoveryData($IsSnapShot)
{
$oAPI = new-object -comobject "MOM.ScriptAPI"
$oDiscoveryDataTmp= $oAPI.CreateDiscoveryData(0, $SourceId, $ManagedEntityId)
$oDiscoveryDataTmp.IsSnapshot = $IsSnapShot

$oDiscoveryDataTmp
}

function DiscoverInstances()
{
$boolUseWIN2012 = CheckByOSCurrentVersion
$timex=get-date -displayhint time
$message = "Started dicovery at machine local time: " + $timex
LogMessage $DBG_TRACE $message
$Err = $null
try{
$oDiscoveryData = $oAPI.CreateDiscoveryData(0, $SourceId, $ManagedEntityId)
}catch{
$Err = $_.Exception.Message
}

If(($oDiscoveryData -eq "") -or ($oDiscoveryData -eq $null))
{
LogMessage $DBG_ERROR "Failed to get Discovery Data Object. MOM v3 must be installed to execute this script"

if($Err -ne $null)
{
$message = "Failed with error " + $Err
LogMessage $DBG_ERROR $message
}

Exit -1
}

WinClusterDiscover $oDiscoveryData $boolUseWIN2012 $HealthServiceName
$timex=get-date -displayhint time
$message = "Finished dicovery at machine local time: " + $timex
LogMessage $DBG_TRACE $message
return $oDiscoveryData
}

#==========================================================================
# Class: WinClusterObject
# Description: base holding object and its properties
#==========================================================================

#==========================================================================
# Discover instance
#==========================================================================
Function WinClusterObjectDiscoverInstance($hostKey, $oObject, $discoveryClass, $oDiscoveryData)
{
$message = "Creating DiscoveryData packet for " + $discoveryClass + "."
LogMessage $DBG_TRACE $message

$oInstance = $oDiscoveryData.CreateClassInstance($discoveryClass)

$name = $oObject.Name

If(($discoveryClass -eq "$MPElement[Name='Microsoft.Windows.Cluster.Group']$") -and ($appendClusterNameToResourceGroup -eq $true))
{
$oInstance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $($name + " (" + $hostKey + ")"))
}Else{
$oInstance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $name)
}

$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Component']/ClusterName$", $hostKey)

$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Component']/ObjectName$", $name.Trim())

#$state
#state = WMIGetProperty $oObject "State" $wbemCimtypeUint32 $ErrAction_ThrowErrorAndAbort
#
#.AddProperty _
# wrap with $...$ when ObjectState is reenabled
# "MPElement[Name='Microsoft.Windows.Cluster.Component']/ObjectState", _
# state

return $oInstance
}
# WinClusterObject

#==========================================================================
# Class: WinCluster
# Description: holding cluster object and its properties
#==========================================================================

#==========================================================================
# Discover cluster classes
#==========================================================================
Function WinClusterDiscover($oDiscoveryData, $boolUseWIN2012, $computerName)
{
$oClusters = $null
if($boolUseWIN2012)
{
try{
$oClusters = Get-CimInstance &#x2013;ComputerName $computerName -Namespace 'root\mscluster' -class "MSCluster_Cluster" -ErrorAction Stop
}catch{
import-module cimcmdlets
$oClusters = Get-CimInstance &#x2013;ComputerName $computerName -Namespace 'root\mscluster' -class "MSCluster_Cluster" -ErrorAction Stop
}
}else{
$oClusters = Get-WmiObject -ComputerName $computerName -Namespace 'root\mscluster' -class "MSCluster_Cluster"
}
ForEach($oCluster in $oClusters)
{
$oClusterInstance = $oDiscoveryData.CreateClassInstance("$MPElement[Name='Cluster!Microsoft.Windows.Cluster']$")
$oClusterInstance.AddProperty("$MPElement[Name='Cluster!Microsoft.Windows.Cluster']/Name$", $oCluster.Name)
# need to make sure that cluster was discovered as it is used in some relationships
$oDiscoveryData.AddInstance($oClusterInstance)

# nodes
$query = "select * from MSCluster_ClusterToNode where Antecedent = ""MSCluster_Cluster.Name=\""" + $oCluster.Name + "\"""""
$oNodes = WMIExecQuery $HealthServiceName "root\mscluster" $query

ForEach($oNode in $oNodes)
{
$oRealNode = WMIGetInstance $HealthServiceName "root\mscluster" $oNode.Dependent

$oNodeInstance = WinClusterNodeDiscoverInstance $oCluster.Name $oRealNode $oDiscoveryData

If($oNodeInstance -ne $null)
{
WinClusterNodeDiscoverClusterContainsRelationship $oClusterInstance $oDiscoveryData
}
}
# networks
$query = "select * from MSCluster_ClusterToNetwork where GroupComponent = ""MSCluster_Cluster.Name=\""" + $oCluster.Name + "\"""""
$oNetworks = WMIExecQuery $HealthServiceName "root\mscluster" $query

ForEach($oNetwork in $oNetworks)
{
$oRealNetwork = WMIGetInstance $HealthServiceName "root\mscluster" $oNetwork.PartComponent

$oNetworkInstance = WinClusterNetworkDiscoverInstance $oCluster.Name $oRealNetwork $oDiscoveryData $boolUseWIN2012

If($oNetworkInstance -ne $null)
{
WinClusterNetworkDiscoverClusterContainsRelationship $oClusterInstance $oCluster.Name $oRealNetwork.Name $oDiscoveryData
}
}

# groups
$query = "select * from MSCluster_ClusterToResourceGroup where GroupComponent = ""MSCluster_Cluster.Name=\""" + $oCluster.Name + "\"""""
$oGroups = WMIExecQuery $HealthServiceName "root\mscluster" $query

$boolMinOSVerCheck = CheckMinOSVer $DBL_MIN_VER_WIN_SRV_2008R2_OSVer
$iGroupCounter = 0


ForEach($oGroup in $oGroups)
{
$oRealGroup = WMIGetInstance $HealthServiceName "root\mscluster" $oGroup.PartComponent

$autoFailbackType = $oRealGroup.AutoFailbackType
$description = $oRealGroup.Description
$failbackWindowEnd = $oRealGroup.FailbackWindowEnd
try{
$failbackWindowStart = [int]$oRealGroup.FailbackWindowStart
}catch{
$failbackWindowStart = "-1"
}
$failoverPeriod = $oRealGroup.FailoverPeriod
try{
$failoverThreshold = [int]$oRealGroup.FailoverThreshold
}catch{
$failoverThreshold = "-1"
}
$persistentState = $oRealGroup.PersistentState


if($boolMinOSVerCheck)
{
#Apply Filter if Any
$GroupType = $oRealGroup.GroupType
If($ObjResourceGroupTypeFilter.Contains($GroupType) -eq $false){
$boolDiscoverGroup = $true
}else{
$boolDiscoverGroup = $false
}
}else{
$boolDiscoverGroup = $true
}

if($boolDiscoverGroup)
{
#Getting Discovered Group Index for comparing it with defined Discovery Limit
$iGroupCounter = $iGroupCounter + 1

# resource group discover limit exceeded?
If($iGroupCounter -gt $ResourceGroupDiscoveryLimit)
{
# yes
# log to event log
$oAPI.LogScriptEvent("DiscoverClustering.ps1", 7010, 1, ($HealthServiceName + " hosts " + $iGroupCounter + " resource groups which exceeds the configured threshold of " + $ResourceGroupDiscoveryLimit + "."))
}else{
# no
# proceed with normal discovery


# undefined is empty string
If($failbackWindowEnd -eq "-1" ){ $failbackWindowEnd = ""}
If($failbackWindowStart -eq "-1"){ $failbackWindowStart = ""}

$oGroupInstance = WinClusterGroupDiscoverInstance $oCluster.Name $oRealGroup $autoFailbackType $description $failbackWindowEnd $failbackWindowStart $failoverPeriod $failoverThreshold $persistentState $oDiscoveryData

#cluster contains groups
If($oGroupInstance -ne $null)
{
WinClusterGroupDiscoverClusterContainsRelationship $oClusterInstance $oCluster.Name $oRealGroup.Name.Trim() $oDiscoveryData
}

$oHostedGroupInstance = WinClusterGroupDiscoverInstanceForHosted $oCluster.Name $oRealGroup $autoFailbackType $description $failbackWindowEnd $failbackWindowStart $failoverPeriod $failoverThreshold $persistentState $oDiscoveryData

# group contains hosted group
WinClusterGroupDiscoverClusterGroupContainsRelationship $oCluster.Name $oRealGroup.Name.Trim() $oDiscoveryData
}

}
}

}

}

# WinCluster

#==========================================================================
# Class: WinClusterNode
# Description: holding cluster node and its properties
#==========================================================================

#==========================================================================
# Discover instance
#==========================================================================
Function WinClusterNodeDiscoverInstance($hostKey, $oObject, $oDiscoveryData)
{
$DiscoverInstance = $null
#======================================================================
# only on same computer
#======================================================================

$name = $oObject.Name
$description = $oObject.Description
$buildNumber =$oObject.BuildNumber
$cSDVersion = $oObject.CSDVersion
$majorVersion = $oObject.MajorVersion
$minorVersion = $oObject.MinorVersion
$nodeHighestVersion = $oObject.NodeHighestVersion
$nodeLowestVersion = $oObject.NodeLowestVersion

If($NetBiosName.ToLower().Equals($name.ToLower()))
{
LogMessage $DBG_TRACE "Creating DiscoveryData packet for Microsoft.Windows.Cluster.Node."

$oInstance = $oDiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Cluster.Node']$")

$oInstance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $HealthServiceName)

$oInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $HealthServiceName)

$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Node']/ClusterName$", $hostKey)

$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Node']/NodeName$", $name.Trim())

#$state
#state = WMIGetProperty $oObject "State" $wbemCimtypeUint32 $ErrAction_ThrowErrorAndAbort
#
#.AddProperty _
# wrap with $...$ when NodeState is reenabled
# "MPElement[Name='Microsoft.Windows.Cluster.Node']/NodeState",
# state

$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Node']/Description$", $description)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Node']/BuildNumber$", $buildNumber)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Node']/CSDVersion$", $cSDVersion)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Node']/MajorVersion$", $majorVersion)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Node']/MinorVersion$", $minorVersion)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Node']/NodeHighestVersion$", $nodeHighestVersion)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Node']/NodeLowestVersion$", $nodeLowestVersion)

#$enableEventLogReplication
#enableEventLogReplication = WMIGetProperty $oObject, "EnableEventLogReplication", $wbemCimtypeBoolean, $ErrAction_None
#
#.AddProperty _
# wrap with $...$ when NodeState is reenabled
# "MPElement[Name='Microsoft.Windows.Cluster.Node']/EnableEventLogReplication", _
# enableEventLogReplication


$oDiscoveryData.AddInstance($oInstance)

WinClusterNodeDiscoverClusterNodeHostsNodeRoleRelationship $hostKey $oObject $oDiscoveryData

return $oInstance
}
}




#==========================================================================
# Discover node hostinging role relationship instance
#==========================================================================
Function WinClusterNodeDiscoverClusterNodeHostsNodeRoleRelationship(
$hostKey,
$oObject,
$oDiscoveryData
){

LogMessage $DBG_TRACE "Creating DiscoveryData packet for node hosting roles."

$oNodeRoleInstance = $oDiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Cluster.NodeRole']$")
$oNodeRoleInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $HealthServiceName)
$oInstance = $oDiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Cluster.Node']$")
$oInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $HealthServiceName)
$oRelationshipInstance = $oDiscoveryData.CreateRelationshipInstance("$MPElement[Name='Windows!Microsoft.Windows.ComputerHostsComputerRole']$")
$oRelationshipInstance.Source = $oInstance
$oRelationshipInstance.Target = $oNodeRoleInstance
$oDiscoveryData.AddInstance($oRelationshipInstance)

$oNodeRoleInstance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $oObject.Name)

$oDiscoveryData.AddInstance($oNodeRoleInstance)
}

#==========================================================================
# Discover cluster contains relationship instance
#==========================================================================
Function WinClusterNodeDiscoverClusterContainsRelationship(
$oClusterInstance,
$oDiscoveryData
)
{

LogMessage $DBG_TRACE "Creating DiscoveryData packet for cluster contains nodes."

$oInstance = $oDiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Cluster.Node']$")

$oInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $HealthServiceName)

DiscoverClusterContainsRelationship $oClusterInstance $oInstance "$MPElement[Name='Microsoft.Windows.Cluster.Contains.Microsoft.Windows.Cluster.Node']$" $oDiscoveryData
}

# WinClusterNode

#==========================================================================
# Class: WinClusterNetwork
# Description: holding cluster network and its properties
#==========================================================================
$roleNone = $false

#==========================================================================
# Discover instance
#==========================================================================
Function WinClusterNetworkDiscoverInstance(
$hostKey,
$oObject,
$oDiscoveryData,
$boolUseWIN2012
){

$oInstance = WinClusterObjectDiscoverInstance $hostKey $oObject "$MPElement[Name='Microsoft.Windows.Cluster.Network']$" $oDiscoveryData

$address = $oObject.Address
$addressMask = $oObject.AddressMask
$role = $oObject.Role
$description = $oObject.Description

If(($role -eq "0") -or ($role -eq $null) -or ($role -eq ""))
{
$roleNone = $true
}

$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Network']/Address$", $address)

$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Network']/AddressMask$", $addressMask)

#.AddProperty _
# wrap with $...$ when Role is reenabled
# "MPElement[Name='Microsoft.Windows.Cluster.Network']/Role", _
# role

$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Network']/Description$", $description)

$discoverNetwork = $true

If($discoverUnusedNetworks -eq $false)
{
If($roleNone -eq $true){
$discoverNetwork = $false
}
}

If($discoverNetwork -eq $true)
{
$oDiscoveryData.AddInstance($oInstance)
$DiscoverInstance = $oInstance
$name = $oObject.Name

#====================================================
# discover contains network interfaces
#====================================================
$query = "select * from MSCluster_NetworkToNetworkInterface where GroupComponent = ""MSCluster_Network.Name=\""" + $name + "\"""""
$oNetworkItfs = WMIExecQuery $HealthServiceName "root\mscluster" $query

ForEach($oNetworkItf in $oNetworkItfs)
{
$oRealNetworkItf = WMIGetInstance $HealthServiceName "root\mscluster" $oNetworkItf.PartComponent

# $strs = $oRealNetworkItf.DeviceID.Split(" - ")
$device = $oRealNetworkItf.DeviceID
$index = $device.LastIndexOf("-")
$temp = $device.Substring($index).Replace("-", "").Trim()
$machine = $device.Substring(0, $index).Trim()

$baseOSItfName = ""
If([string]::Compare($machine.ToLower() , ($oRealNetworkItf.SystemName).ToLower(), $true)){
$baseOSItfName = $machine
}Else{
$baseOSItfName = $temp
}
$message = "Network: " + $name + " interface: " + $baseOSItfName
LogMessage $DBG_TRACE $message
if(-not ($oRealNetworkItf.SystemName).ToLower().Equals($NetBiosName.ToLower()))
{
continue
}
$deviceID = WinClusterNetworkInterfaceDiscoverInstance $hostKey $baseOSItfName $oRealNetworkItf $oDiscoveryData $boolUseWIN2012

# discover that network contains interfaces
WinClusterNetworkDiscoverContainsNetworkInterfacesRelationship $hostKey $name $deviceID $oRealNetworkItf $oDiscoveryData
}
}Else{
$DiscoverInstance = $null
}
return $DiscoverInstance
}
#==========================================================================
# Discover cluster containing network interfaces relationship instance
#==========================================================================
Function WinClusterNetworkDiscoverContainsNetworkInterfacesRelationship(
$hostKey,
$networkKey,
$networkItfKey,
$oRealNetworkItf,
$oDiscoveryData
){

If(($NetBiosName).ToLower().Equals(($oRealNetworkItf.SystemName).ToLower()))
{
LogMessage $DBG_TRACE "Creating DiscoveryData packet for cluster network contains network interfaces."
$oNetworkInstance = $oDiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Cluster.Network']$")
$oNetworkInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Component']/ClusterName$",$hostKey)
$oNetworkInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Component']/ObjectName$",$networkKey)
$oInstance = $oDiscoveryData.CreateClassInstance($NetworkInterfaceTypeGuid)
$oInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$",$HealthServiceName)
$oInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.LogicalDevice']/DeviceID$",$networkItfKey)
$oRelationshipInstance = $oDiscoveryData.CreateRelationshipInstance($NetworkContainsInterfaceGuid)
$oRelationshipInstance.Source = $oNetworkInstance
$oRelationshipInstance.Target = $oInstance
$oDiscoveryData.AddInstance($oRelationshipInstance)
}
}

#==========================================================================
# Discover cluster contains relationship instance
#==========================================================================
Function WinClusterNetworkDiscoverClusterContainsRelationship(
$oClusterInstance,
$hostKey,
$networkKey,
$oDiscoveryData
){
If($roleNone -eq $false)
{
LogMessage $DBG_TRACE "Creating DiscoveryData packet for cluster contains network."
$oInstance = $oDiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Cluster.Network']$")
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Component']/ClusterName$", $hostKey)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Component']/ObjectName$", $networkKey)
DiscoverClusterContainsRelationship $oClusterInstance $oInstance "$MPElement[Name='Microsoft.Windows.Cluster.Contains.Microsoft.Windows.Cluster.Network']$" $oDiscoveryData
}
}
# WinClusterNetwork


#==========================================================================
# Discover instance
#==========================================================================
Function WinClusterNetworkInterfaceDiscoverInstance(
$clusterKey,
$networkItfKey,
$oObject,
$oDiscoveryData,
$boolUseWIN2012
){
$message = "Creating DiscoveryData packet for " + $networkInterfaceTypeGuid
LogMessage $DBG_TRACE $message

$oInstance = $oDiscoveryData.CreateClassInstance($networkInterfaceTypeGuid)
$oInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $HealthServiceName)

$adapter = $oObject.Adapter
$address = $oObject.Address
$description = $oObject.Description
$name = $oObject.DeviceID
If($discoverUnusedNetworks -eq $false)
{
$query = "select * from Win32_NetworkAdapter Where NetConnectionID = ""$networkItfKey"" and NetConnectionStatus != 0"

}Else{
$query = "select * from Win32_NetworkAdapter Where NetConnectionID = ""$networkItfKey"""
}

$owObj = WMIExecQuery $HealthServiceName "root\cimv2" $query

$deviceID = $owObj.DeviceID
$adapterType = $owObj.AdapterType
$index = $owObj.Index
$manufacturer = $owObj.Manufacturer
$macAddress = $owObj.MACAddress
# replaces colons in MAC with dashes to comply with IEEE 802 and NASM
$macAddress = $macAddress.Replace(":", "-")
$serviceName = $owObj.ServiceName
$oInstance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $networkItfKey)
$oInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.LogicalDevice']/Name$", $adapter)
$oInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.LogicalDevice']/DeviceID$", $deviceID)
If(($description -eq "") -or ($description -eq $null))
{
$oInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.LogicalDevice']/Description$", $adapter)
}Else{
$oInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.LogicalDevice']/Description$", $description)
}

$oInstance.AddProperty("$MPElement[Name='Server!Microsoft.Windows.Server.NetworkAdapter']/IPAddress$", $address)
$oInstance.AddProperty("$MPElement[Name='Server!Microsoft.Windows.Server.NetworkAdapter']/AdapterType$", $adapterType)
$oInstance.AddProperty("$MPElement[Name='Server!Microsoft.Windows.Server.NetworkAdapter']/Index$", $index)
$oInstance.AddProperty("$MPElement[Name='Server!Microsoft.Windows.Server.NetworkAdapter']/Manufacturer$", $manufacturer)
$oInstance.AddProperty("$MPElement[Name='Server!Microsoft.Windows.Server.NetworkAdapter']/MACAddress$", $macAddress)
$oInstance.AddProperty("$MPElement[Name='Server!Microsoft.Windows.Server.NetworkAdapter']/ServiceName$", $serviceName)
$oInstance.AddProperty($networkInterfacePropClusterNameGuid, $clusterKey)
$oInstance.AddProperty($networkInterfacePropNameGuid, $name)

If($boolUseWIN2012)
{
$strClusterAdapterID = $oObject.AdapterId
$strClusterAdapterID = $strClusterAdapterID.Replace("{", "")
$strClusterAdapterID = $strClusterAdapterID.Replace("}", "")
if(($strNetworkInterfacePropClusterAdapterID -ne $null) -and ($strNetworkInterfacePropClusterAdapterID -ne ""))
{
$oInstance.AddProperty($strNetworkInterfacePropClusterAdapterID, $strClusterAdapterID)
}
}

$oDiscoveryData.AddInstance($oInstance)
return $deviceID;
}
# WinClusterNetworkInterface

#===================================================================================
# Class: WinClusterGroup
# Description: holding group object and its properties
#==========================================================================

#==========================================================================
# Discover instance
#==========================================================================
Function WinClusterGroupDiscoverInstance(
$hostKey,
$oObject,
$autoFailbackType,
$description,
$failbackWindowEnd,
$failbackWindowStart,
$failoverPeriod,
$failoverThreshold,
$persistentState,
$oDiscoveryData
)
{

# instance

$oInstance = WinClusterObjectDiscoverInstance $hostKey $oObject "$MPElement[Name='Microsoft.Windows.Cluster.Group']$" $oDiscoveryData

$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Group']/OriginalGroupName$", $oObject.Name)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Group']/AutoFailbackType$", $autoFailbackType)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Group']/Description$", $description)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Group']/FailbackWindowEnd$", $failbackWindowEnd)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Group']/FailbackWindowStart$", $failbackWindowStart)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Group']/FailoverPeriod$", $failoverPeriod)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Group']/FailoverThreshold$", $failoverThreshold)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Group']/PersistentState$", $persistentState)
$e = $null

$oActiveNode = $null
try{
$query = "select * from MSCluster_NodeToActiveGroup where PartComponent = ""MSCluster_ResourceGroup.Name=\""" + $oObject.Name + "\"""""
$oActiveNode = WMIExecQuery $HealthServiceName "root\mscluster" $query
}catch{
$e = $_.Exception.Message
}

If(($oActiveNode -eq $null) -or ($e -ne $null)){
ThrowScriptError "The Query for active node returned an invalid result set. Please check to see if this is a valid WMI Query." e
}

If($oActiveNode -ne $null)
{
ForEach($oNode in $oActiveNode)
{
$oActive = $oNode.GroupComponent

If($oActive -eq $null)
{
ThrowScriptError "Do not get a Node. Please check to see if this is a valid WMI Query." e
}

$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Group']/GroupActiveOnNodeDuringDiscovery$", $oActive.Name)
}
}Else{
# need to use current node
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Group']/GroupActiveOnNodeDuringDiscovery$", $NetBiosName)
}

$oDiscoveryData.AddInstance($oInstance)

#====================================================
# discover resources
#====================================================
$query = "select * from MSCluster_ResourceGroupToResource where GroupComponent = ""MSCluster_ResourceGroup.Name=\""" + $oObject.Name + "\"""""
$oResources = WMIExecQuery $HealthServiceName "root\mscluster" $query

ForEach($oResource in $oResources)
{
$oRealResource = WMIGetInstance $HealthServiceName "root\mscluster" $oResource.PartComponent

# discovery enabled?
if($discoverNonCSVResources -eq $true)
{
# yes
WinClusterResourceDiscoverInstance $hostKey $oObject.Name.trim() $oRealResource $oDiscoveryData

# discover that group hosts this resource
WinClusterResourceDiscoverClusterGroupHostsResourcesRelationship $hostKey $oObject.Name.Trim() $oRealResource.Name.Trim() $oDiscoveryData
}
}

# cluster shared volume discovery enabled and available storage group?
$boolUseWIN2012 = CheckByOSCurrentVersion

if($boolUseWIN2012)
{
$resourceGroupType = ($oObject | Invoke-CimMethod -MethodName GetGroupType).ReturnValue
}else{
$resourceGroupType = $oObject.GetGroupType().ReturnValue
}
if(($discoverCSVResources -eq $true) -and ($resourceGroupType -eq 2))
{
$query = "select * from MSCluster_Resource where IsClusterSharedVolume = true"
$oClusterSharedVolumes = WMIExecQuery $HealthServiceName "root\mscluster" $query

foreach($oCSV in $oClusterSharedVolumes)
{
WinClusterResourceDiscoverInstance $hostKey $oObject.Name.Trim() $oCSV $oDiscoveryData
WinClusterResourceDiscoverClusterGroupHostsResourcesRelationship $hostKey $oObject.Name.Trim() $oCSV.Name.Trim() $oDiscoveryData
}
}
return $oInstance
}

#==========================================================================
# Discover cluster contains relationship instance
#==========================================================================
Function WinClusterGroupDiscoverClusterContainsRelationship(
$oClusterInstance,
$hostKey,
$groupKey,
$oDiscoveryData
)
{
LogMessage $DBG_TRACE "Creating DiscoveryData packet for cluster contains groups."

$oInstance = $oDiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Cluster.Group']$")

$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Component']/ClusterName$", $hostKey)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Component']/ObjectName$", $groupKey.Trim())

DiscoverClusterContainsRelationship $oClusterInstance $oInstance "$MPElement[Name='Microsoft.Windows.Cluster.Contains.Microsoft.Windows.Cluster.Group']$" $oDiscoveryData

}

#==========================================================================
# Discover cluster node hosted group
#==========================================================================
Function WinClusterGroupDiscoverInstanceForHosted(
$hostKey,
$oObject,
$autoFailbackType,
$description,
$failbackWindowEnd,
$failbackWindowStart,
$failoverPeriod,
$failoverThreshold,
$persistentState,
$oDiscoveryData
)
{
# instance
$oHostedGroupInstance = $oDiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']$")
$oHostedGroupInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $HealthServiceName)
$oHostedGroupInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']/ClusterName$", $hostKey)
$oHostedGroupInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']/NodeName$", $NetBiosName)

$oHostedGroupInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']/GroupName$", $oObject.Name.Trim())
$oHostedGroupInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']/EscapedGroupName$", $oObject.Name)

#oHostedGroupInstance.AddProperty _
# wrap with $...$ when GroupState is reenabled
# "MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']/GroupState", _
# oObject.State

$oHostedGroupInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']/AutoFailbackType$", $autoFailbackType)
$oHostedGroupInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']/Description$", $description)
$oHostedGroupInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']/FailbackWindowEnd$", $failbackWindowEnd)
$oHostedGroupInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']/FailbackWindowStart$", $failbackWindowStart)
$oHostedGroupInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']/FailoverPeriod$", $failoverPeriod)
$oHostedGroupInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']/FailoverThreshold$", $failoverThreshold)
$oHostedGroupInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']/PersistentState$", $persistentState)

$oDiscoveryData.AddInstance($oHostedGroupInstance)
return $oHostedGroupInstance

}

#==========================================================================
# Discover cluster contains relationship instance
#==========================================================================
Function WinClusterGroupDiscoverClusterGroupContainsRelationship(
$hostKey,
$groupKey,
$oDiscoveryData
)
{

LogMessage $DBG_TRACE "Creating DiscoveryData packet for cluster group contains hosted groups."

$oInstance = $oDiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Cluster.Group']$")

$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Component']/ClusterName$", $hostKey)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Component']/ObjectName$", $groupKey.Trim())

$oHostedInstance = $oDiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']$")

$oHostedInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $HealthServiceName)
$oHostedInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']/ClusterName$", $hostKey)
$oHostedInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']/NodeName$", $NetBiosName)
$oHostedInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']/GroupName$", $groupKey)

$oRelationshipInstance = $oDiscoveryData.CreateRelationshipInstance("$MPElement[Name='Microsoft.Windows.Cluster.Group.Contains.Microsoft.Windows.Cluster.HostedGroup']$")

$oRelationshipInstance.Source = $oInstance
$oRelationshipInstance.Target = $oHostedInstance

$oDiscoveryData.AddInstance($oRelationshipInstance)
}

# WinClusterGroup

#==========================================================================
# Class: WinClusterResource
# Description: holding cluster resource extension and its properties
#==========================================================================

#==========================================================================
# Discover instance
#==========================================================================
Function WinClusterResourceDiscoverInstance(
$clusterKey,
$groupKey,
$oObject,
$oDiscoveryData
)
{
LogMessage $DBG_TRACE "Creating DiscoveryData packet for Microsoft.Windows.Cluster.Resource."

$name = $oObject.Name
$typeName = $oObject.Type
$description = $oObject.Description
try{
$isAlivePollInterval = [int]$oObject.IsAlivePollInterval
}catch{
$isAlivePollInterval = "-1"
}
try{
$looksAlivePollInterval = [int]$oObject.LooksAlivePollInterval
}catch{
$looksAlivePollInterval = "-1"
}
$pendingTimeout = $oObject.PendingTimeout
$persistentState = $oObject.PersistentState
$restartAction = $oObject.RestartAction
$restartPeriod = $oObject.RestartPeriod
$restartThreshold = $oObject.RestartThreshold
$retryPeriodOnFailure = $oObject.RetryPeriodOnFailure
$separateMonitor = $oObject.SeparateMonitor

$oInstance = $oDiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Cluster.Resource']$")

$oInstance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $name)
$oInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $HealthServiceName)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']/ClusterName$", $clusterKey)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']/NodeName$", $NetBiosName)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']/GroupName$", $groupKey)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Resource']/ResourceName$", $name.Trim())
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Resource']/EscapedResourceName$", $name)

#$state
#state = WMIGetProperty $oObject "State" $wbemCimtypeUint32 ErrAction_ThrowErrorAndAbort
#
#.AddProperty _
# wrap with $...$ when ResourceState is reenabled
# "MPElement[Name='Microsoft.Windows.Cluster.Resource']/ResourceState", _
# state

$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Resource']/ResourceTypeName$", $typeName)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Resource']/Description$", $description)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Resource']/IsAlivePollInterval$", $isAlivePollInterval)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Resource']/LooksAlivePollInterval$", $looksAlivePollInterval)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Resource']/PendingTimeout$", $pendingTimeout)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Resource']/PersistentState$", $persistentState)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Resource']/RestartAction$", $restartAction)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Resource']/RestartPeriod$", $restartPeriod)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Resource']/RestartThreshold$", $restartThreshold)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Resource']/RetryPeriodOnFailure$", $retryPeriodOnFailure)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Resource']/SeparateMonitor$", $separateMonitor)

$oDiscoveryData.AddInstance($oInstance)
}

#==========================================================================
# Discover group hostinging resources relationship instance
#==========================================================================
Function WinClusterResourceDiscoverClusterGroupHostsResourcesRelationship(
$hostKey,
$groupKey,
$resKey,
$oDiscoveryData
)
{
LogMessage $DBG_TRACE "Creating DiscoveryData packet for group containing resources.."

$oInstance = $oDiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']$")

$oInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $HealthServiceName)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']/ClusterName$", $hostKey)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']/NodeName$", $NetBiosName)
$oInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']/GroupName$", $groupKey)

$oClusterResourceInstance = $oDiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Cluster.Resource']$")

$oClusterResourceInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $HealthServiceName)
$oClusterResourceInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']/ClusterName$", $hostKey)
$oClusterResourceInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']/NodeName$", $NetBiosName)
$oClusterResourceInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup']/GroupName$", $groupKey)
$oClusterResourceInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Cluster.Resource']/ResourceName$", $resKey)

$oRelationshipInstance = $oDiscoveryData.CreateRelationshipInstance("$MPElement[Name='Microsoft.Windows.Cluster.HostedGroup.Hosts.Microsoft.Windows.Cluster.Resource']$")

$oRelationshipInstance.Source = $oInstance
$oRelationshipInstance.Target = $oClusterResourceInstance
$oDiscoveryData.AddInstance($oRelationshipInstance)
}

# WinClusterResource

#==========================================================================
# Description: HELPERS
#==========================================================================

#==========================================================================
# Class: ClusterUtil
# Description: Utility methods for clustering
#==========================================================================

#**********************************************************************
Function WMIExecQuery($computerName, $sNamespace, $sQuery)
{
$e = $null
$oQuery = $null
$boolUseWIN2012 = CheckByOSCurrentVersion
try {
if($boolUseWIN2012)
{
try{
$oQuery = Get-CimInstance -Namespace $sNamespace &#x2013;ComputerName $computerName -Query $sQuery -ErrorVariable ProcessError -ErrorAction Stop
}catch{
import-module cimcmdlets
$oQuery = Get-CimInstance -Namespace $sNamespace &#x2013;ComputerName $computerName -Query $sQuery -ErrorVariable ProcessError -ErrorAction Stop
}
}else{
$oQuery = Get-WmiObject -ComputerName $computerName -Namespace $sNamespace -Query $sQuery -ErrorVariable ProcessError -ErrorAction Stop
}

}catch{
$e = $_.Exception.Message
}

If($oQuery -eq $null)
{
$m = "No Such Object." + $sQuery
LogMessage $DBG_TRACE "No Such Object." + $m
}
If($e -ne $null)
{
$message = "The Query '" + $sQuery + "' returned an invalid result set. Please check to see if this is a valid WMI Query."
ThrowScriptError $message $e
}

return $oQuery
}

Function WMIGetInstance($computerName, $sNamespace, $sInstancePath)
{
$e = $null
$oInstance = $null
$temp = ""
if($sInstancePath -eq $null)
{
return
}else{
$sInstancePath = $sInstancePath.ToString()
}
$temp = $sInstancePath.split("(")
$query = "select * from "+ $temp[0] + " where " + $temp[1]
$query = $query.Replace(","," and ").Replace(")", "")
try
{
if($boolUseWIN2012)
{
try{
$oInstance = Get-CimInstance &#x2013;ComputerName $computerName -Namespace $sNamespace -Query $query -ErrorVariable ProcessError -ErrorAction Stop
}catch{
import-module cimcmdlets
$oInstance = Get-CimInstance &#x2013;ComputerName $computerName -Namespace $sNamespace -Query $query -ErrorVariable ProcessError -ErrorAction Stop
}
}else{
$oInstance = Get-WmiObject -ComputerName $computerName -Namespace $sNamespace -Query $query -ErrorVariable ProcessError -ErrorAction Stop
}
}catch{
$e = $_.Exception.Message
}

If($oInstance -eq $null)
{
$message = "The class name '" + $sInstancePath + "' returned no instances. Please check to see if this is a valid WMI class name."
ThrowScriptError $message $e
}
return $oInstance
}

#==========================================================================
# Discover cluster contains relationship instance
#==========================================================================
function DiscoverClusterContainsRelationship(
$oSourceInstance,
$oTargetInstance,
$discoveryRelationshipClass,
$oDiscoveryData
)
{
LogMessage $DBG_TRACE "Creating DiscoveryData packet for cluster contains objects."

$oRelationshipInstance = $oDiscoveryData.CreateRelationshipInstance($discoveryRelationshipClass)

$oRelationshipInstance.Source = $oSourceInstance
$oRelationshipInstance.Target = $oTargetInstance

$oDiscoveryData.AddInstance($oRelationshipInstance)
}
#ClusterUtil

function ThrowScriptErrorNoAbort($sMessage, $oErrDes)
{
$message = $sMessage + "`n" + $oErrDes
LogMessage $DBG_ERROR $message
}

function ThrowScriptError($sMessage, $oErrDes)
{
ThrowScriptErrorNoAbort $sMessage $oErrDes
ThrowEmptyDiscoveryData $false
Quit
}

function Quit()
{
LogMessage $DBG_ERROR "Terminated on error!"
Exit -1
}

#======================================================================
# 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.
#======================================================================
function LogMessage($nLevel, $strMessage)
{
if($nLevel -ge $m_nDebugLevel)
{
if($nLevel -eq $DBG_ERROR){
Write-Host "[Error]: " $strMessage;
}elseif ($nLevel -eq $DBG_WARNING) {
Write-Host "[Warning]: " $strMessage;
} elseif ($nLevel -eq $DBG_TRACE) {
Write-Host "[Trace]: " $strMessage;
}
}
}

$DBG_NONE = 1
$DBG_ERROR = 2
$DBG_WARNING = 3
$DBG_TRACE = 4
$m_nDebugLevel = $DBG_ERROR

$ErrAction_None = 0
$ErrAction_Trace = 1
$ErrAction_ThrowError = 16
$ErrAction_Abort = 32
$ErrAction_ThrowErrorAndAbort = 48

$DBL_MIN_VER_WIN_SRV_2008R2_OSVer = 6.1
$WIN_SRV_2012_OSVer = "6.2"
$WIN_SRV_2012R2_OSVer = "6.3"
$DefaultClusterGroupTypes = ""

#==========================================================================
# Initialize the arguments in Script
#==========================================================================

If(($appendClusterNameToResourceGroup.length -eq 0) -or ($appendClusterNameToResourceGroup -eq $null)) {
$appendClusterNameToResourceGroup = $false
}
Else{
$appendClusterNameToResourceGroup = $true
}

If(($strNetworkInterfacePropClusterAdapterID.length -eq 0) -or ($strNetworkInterfacePropClusterAdapterID -eq $null)){
$strNetworkInterfacePropClusterAdapterID = ""
}

#Adding New Parameter for Resource Group Types Filter
If(($strResourceGroupTypeFilter.length -eq 0) -or ($strResourceGroupTypeFilter -eq $null)){
$strResourceGroupTypeFilter = $DefaultClusterGroupTypes
}
$ObjResourceGroupTypeFilter = $strResourceGroupTypeFilter.Split(",")

$message = "SourceId : " + $SourceId
LogMessage $DBG_TRACE $message
$message = "ManagedEntityId : " + $ManagedEntityId
LogMessage $DBG_TRACE $message
$message = "HealthServiceName : " + $HealthServiceName
LogMessage $DBG_TRACE $message
#==========================================================================
# Main
#==========================================================================

$Err = $null
try{
$oAPI = new-object -comobject "MOM.ScriptAPI"
}catch{
$Err = $_.Exception.Message
}
If(($oAPI -eq "") -or ($oAPI -eq $null))
{
LogMessage $DBG_ERROR "Failed to get Discovery API. MOM v3 must be installed to execute this script"
if($Err -ne $null)
{
$message = "Failed with error " + $Err
LogMessage $DBG_ERROR $message
}
}

$deviceID = ""
$adapterType = ""
$index = ""
$manufacturer = ""
$macAddress = ""
$serviceName = ""

DiscoverInstances</Script></ScriptBody>
<Parameters>
<Parameter>
<Name>SourceId</Name>
<Value>$Config/DiscoverySourceId$</Value>
</Parameter>
<Parameter>
<Name>ManagedEntityId</Name>
<Value>$Target/Id$</Value>
</Parameter>
<Parameter>
<Name>HealthServiceName</Name>
<Value>$Target/Host/Property[Type='Windows!Microsoft.Windows.Computer']/PrincipalName$</Value>
</Parameter>
<Parameter>
<Name>NetBiosName</Name>
<Value>$Target/Host/Property[Type='Windows!Microsoft.Windows.Computer']/NetbiosComputerName$</Value>
</Parameter>
<Parameter>
<Name>discoverUnusedNetworks</Name>
<Value>$Config/DiscoverUnusedNetworks$</Value>
</Parameter>
<Parameter>
<Name>networkContainsInterfaceGuid</Name>
<Value>$Config/NetworkContainsInterfaceGuid$</Value>
</Parameter>
<Parameter>
<Name>networkInterfaceTypeGuid</Name>
<Value>$Config/NetworkInterfaceTypeGuid$</Value>
</Parameter>
<Parameter>
<Name>networkInterfacePropClusterNameGuid</Name>
<Value>$Config/NetworkInterfacePropClusterNameGuid$</Value>
</Parameter>
<Parameter>
<Name>networkInterfacePropNameGuid</Name>
<Value>$Config/NetworkInterfacePropNameGuid$</Value>
</Parameter>
<Parameter>
<Name>discoverCSVResources</Name>
<Value>$Config/DiscoverCSVResources$</Value>
</Parameter>
<Parameter>
<Name>discoverNonCSVResources</Name>
<Value>$Config/DiscoverNonCSVResources$</Value>
</Parameter>
<Parameter>
<Name>ResourceGroupDiscoveryLimit</Name>
<Value>$Config/ResourceGroupDiscoveryLimit$</Value>
</Parameter>
<Parameter>
<Name>appendClusterNameToResourceGroup</Name>
<Value>$Config/AppendClusterNameToResourceGroupName$</Value>
</Parameter>
<Parameter>
<Name>strNetworkInterfacePropClusterAdapterID</Name>
<Value>$Config/NetworkInterfacePropClusterAdapterID$</Value>
</Parameter>
<Parameter>
<Name>strResourceGroupTypeFilter</Name>
<Value>$Config/ResourceGroupTypeFilter$</Value>
</Parameter>
</Parameters>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
</ProbeAction>
</MemberModules>
<Composition>
<Node ID="Script"/>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.Discovery.Data</OutputType>
<InputType>System!System.BaseData</InputType>
</ProbeActionModuleType>