Обнаруживает источник данных сценария имени кластера

Microsoft.Windows.Server.ClusterSharedVolumeMonitoring.VirtualServer.DiscoverClusterName.ScriptDataSource.NanoServer (DataSourceModuleType)

Этот модуль выполняет обнаружение начальных объектов кластера Nano Server.

Element properties:

TypeDataSourceModuleType
IsolationAny
AccessibilityInternal
RunAsDefault
OutputTypeSystem.Discovery.Data

Member Modules:

ID Module Type TypeId RunAs 
Scheduler DataSource Microsoft.Windows.Universal.Script.Discovery.DS Default

Overrideable Parameters:

IDParameterTypeSelectorDisplay NameDescription
IntervalSecondsint$Config/IntervalSeconds$Интервал (с)
LogSuccessEventbool$Config/LogSuccessEvent$Регистрация успешного события
ScriptGroupIdstring$Config/ScriptGroupId$
TimeoutSecondsint$Config/TimeoutSeconds$Время ожидания (с)

Source Code:

<DataSourceModuleType ID="Microsoft.Windows.Server.ClusterSharedVolumeMonitoring.VirtualServer.DiscoverClusterName.ScriptDataSource.NanoServer" Accessibility="Internal" Batching="false">
<Configuration>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="IntervalSeconds" type="xsd:int"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="LogSuccessEvent" type="xsd:boolean"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="ScriptGroupId" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="MPElementID" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="TargetID" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="TargetComputer" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="TimeoutSeconds" type="xsd:int"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int"/>
<OverrideableParameter ID="LogSuccessEvent" Selector="$Config/LogSuccessEvent$" ParameterType="bool"/>
<OverrideableParameter ID="ScriptGroupId" Selector="$Config/ScriptGroupId$" ParameterType="string"/>
<OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int"/>
</OverrideableParameters>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<DataSource ID="Scheduler" TypeID="Microsoft.Windows.Universal.Script.Discovery.DS">
<IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
<cScriptName>Microsoft.Windows.Server.CSV.DiscoverClusterNameNano.vbs</cScriptName>
<cScriptParameters>"$Config/MPElementID$" "$Config/TargetID$"</cScriptParameters>
<cScriptBody>Option Explicit
SetLocale("en-us")

Const SCRIPT_VERSION = "2.0"

'Event constants
Const EVENT_TYPE_SUCCESS = 0
Const EVENT_TYPE_ERROR = 1
Const EVENT_TYPE_WARNING = 2
Const EVENT_TYPE_INFORMATION = 4

Const EVENT_ID_SUCCESS = 1000 'Use IDs in the range 1 - 1000
Const EVENT_ID_SCRIPTERROR = 999 'Then you can use eventcreate.exe to test the MP



Call Main

'*********************************************************************************************
' PROCEDURE: Main
' DESCRIPTION: Reads the script parameters, gets the cluster name and
' discovers the containment relationship between a cluster and
' the targeted cluster virtual server.
' PARAMETERS: void
'*********************************************************************************************
Private Sub Main()

' Targeted at Microsoft.Windows.Cluster.VirtualServer (based on Microsoft.Windows.Server.Computer)

Dim strSourceId
Dim strManagedEntityId
Dim objDiscoveryData 'As DiscoveryData
Dim objMomScriptAPI

On Error Resume Next
Err.Clear
Set objMomScriptAPI = CreateObject("MOM.ScriptAPI")

If Err.Number &lt;&gt; 0 Then
Exit Sub
End If

If Not GetScriptParameters(strSourceId, strManagedEntityId) Then
strSourceId = "$MPElement$"
strManagedEntityId = "$Target/Id$"

End If
Err.Clear

'Create new discovery data object
Set objDiscoveryData = objMomScriptAPI.CreateDiscoveryData(0, strSourceId, strManagedEntityId)
If Err.Number &lt;&gt; 0 Then
WScript.Quit(-1)
End If

Call objMomScriptAPI.Return(objDiscoveryData)

On Error Goto 0
End Sub





'******************************************************************************
' FUNCTION: GetScriptParameters
' DESCRIPTION: Reads the script's parameters
' and sets the global variables.
'
' PARAMETERS: OUT String strSourceID: Id of MP element ($MPElement$)
' OUT String strManagedEntityId: Id of targeted entity ($Target/Id$)
' OUT String strTargetComputer: Principal name of executing computer
' ($Target/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$)
' RETURNS: Boolean: True if successful
'******************************************************************************
Private Function GetScriptParameters(ByRef strSourceID, ByRef strManagedEntityId) 'As Boolean

Dim objArguments

On Error Resume Next

Err.Clear
GetScriptParameters = False
'cmdline: &lt;script&gt; True|False &lt;path to debug log&gt; True|False &lt;script id&gt; .MPElement. .Target/Id. .Target/Property[Name="Windows!Microsoft.Windows.Computer"]/PrincipalName.
Set objArguments = WScript.Arguments
If objArguments.Count &lt; 2 Then Exit Function


strSourceID = Replace(objArguments(0), Chr(34), "")
strManagedEntityId = Replace(objArguments(1), Chr(34), "")

If Len(strSourceID) &gt; 0 And Len(strManagedEntityId) &gt; 0 Then GetScriptParameters = True

On Error Goto 0

End Function
</cScriptBody>
<PsScriptName>Microsoft.Windows.Server.CSV.DiscoverClusterName.ps1</PsScriptName>
<PowerShellScriptParameters>'$Config/LogSuccessEvent$' '$Config/MPElementID$' '$Config/TargetID$' '$Config/TargetComputer$'</PowerShellScriptParameters>
<PowerShellScriptParam>param($LogSuccessEvent,$SourceId, $ManagedEntityId,$TargetComputer)</PowerShellScriptParam>
<PowerShellScriptBody>$SCRIPT_VERSION = "2.0"

#Event constants
$EVENT_TYPE_SUCCESS = 0
$EVENT_TYPE_ERROR = 1
$EVENT_TYPE_WARNING = 2
$EVENT_TYPE_INFORMATION = 4

$EVENT_ID_SUCCESS = 1000 #Use IDs in the range 1 - 1000
$EVENT_ID_SCRIPTERROR = 999 #Then you can use eventcreate.exe to test the MP
$Windows2016VersionPrefix = "10.0"
$WMI_NAMESPACE = "root\cimv2"
$WMI_OsCLASS = "Win32_OperatingSystem"
$SeedClassName = "$MPElement[Name='Microsoft.Windows.Server.ClusterSharedVolumeMonitoring.Cluster.NewOS']$"

#*********************************************************************************************
# PROCEDURE: Main
# DESCRIPTION: Reads the script parameters and creates the cluster seed discovery data for Nano Server.
# PARAMETERS: void
#*********************************************************************************************
Function Main()
{
$ErrorActionPreference = 'SilentlyContinue'
$error.Clear()
$objMomScriptAPI = New-Object -comObject MOM.ScriptAPI -ErrorAction SilentlyContinue
if ($null -eq $objMomScriptAPI)
{
Throw-ScriptError -Message "Cannot Initialize MOM Script API"
}

$result = Init-ScomHelper

if ($false -eq $result)
{
LogScriptEvent -LogType 0 -EventId $EVENT_ID_SCRIPTERROR -EventLevel $EVENT_TYPE_WARNING -Message "`nAn error occurred while running script. Cannot iniatialize Discovery Data Serialization Object" -objMomScriptAPI $objMomScriptAPI
return
}

$mblnLogSuccessEvent = Convert-ToBoolean -sBool $LogSuccessEvent
$useCIM = CheckCmdLets
$error.Clear()
#Create new discovery data object
$objDiscoveryData = $objMomScriptAPI.CreateDiscoveryData(0, $SourceId, $ManagedEntityId)

if ($error.Count -ne 0 -or $null -eq $objDiscoveryData)
{
LogScriptEvent -LogType 0 -EventId $EVENT_ID_SCRIPTERROR -EventLevel $EVENT_TYPE_WARNING -Message "`nAn error occurred while running script. Cannot Creata Discovery Data Object" -objMomScriptAPI $objMomScriptAPI
Throw-ScriptError -Message "An error occurred while running script. Cannot Creata Discovery Data Object."
}

$strClusterName = Get-ClusterName -useCim $useCIM
$error.Clear()

#Discover instances
$intSuccess = DiscoverClusterName -strTargetComputer $TargetComputer -strClusterName $strClusterName -objDiscoveryData $objDiscoveryData -useCIM $useCIM

if ($intSuccess -eq $SCRIPT_SUCCESS)
{
if ($mblnLogSuccessEvent -eq $true)
{
LogScriptEvent -LogType 0 -EventId $EVENT_ID_SUCCESS -EventLevel $EVENT_TYPE_INFORMATION -Message "`nScript executed successfully." -objMomScriptAPI $objMomScriptAPI
}


}
else
{
$objDiscoveryData = $objMomScriptAPI.CreateDiscoveryData(0, $strSourceID, $strManagedEntityId)
$objDiscoveryData.IsSnapshot = $false
LogScriptEvent -LogType 0 -EventId $EVENT_ID_SCRIPTERROR -EventLevel $EVENT_TYPE_WARNING -Message "`nAn error occurred while running script" -objMomScriptAPI $objMomScriptAPI
}

$SerializeDiscoveryData = [Scom.Helper.ConvertData]::GetDataItemFromOutput($objDiscoveryData)
Write-Host "$SerializeDiscoveryData"

}


#****************************************************************************************************************
# FUNCTION: DiscoverClusterSharedVolumes
# DESCRIPTION: Discover instances of the class #Microsoft.Windows.Server.ClusterSharedVolumeMonitoring.ClusterSharedVolume# using WMI.
# PARAMETERS: IN String strTargetComputer: principal name of the targeted #Microsoft.Windows.Cluster.VirtualServer# instance.
# IN String strClusterName: the cluster containing the cluster shared volume
# OUT Object objDiscoveryData: initialised DiscoveryData instance
# RETURNS: Integer: 0 if successful and 1 if fails
#****************************************************************************************************************
Function DiscoverClusterName([string]$strTargetComputer, [string]$strClusterName, $objDiscoveryData,$useCIM) #As Integer
{
$iResult = $SCRIPT_SUCCESS
$IsNano = Check-OsVersion -useCim $useCIM

if (-Not $IsNano -or [string]::IsNullOrEmpty($strClusterName) )
{
return $SCRIPT_SUCCESS
}


$iResult = CreateDiscoveryData -strTargetComputer $strTargetComputer -strClusterName $strClusterName -objDiscoveryData $objDiscoveryData
return $iResult
}

# RETURNS: Integer: 0 if successful or 1 if Error
#****************************************************************************************************************
Function CreateDiscoveryData($strTargetComputer, $strClusterName, $objDiscoveryData) #As Integer
{

if ($null -eq $objDiscoveryData)
{
$iResult = $SCRIPT_SUCCESS
return $iResult
}

$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$error.Clear()
$iResult = $SCRIPT_WITH_ERROR

$objInstance = $objDiscoveryData.CreateClassInstance($SeedClassName)

#PrincipalName (host, key)
$objInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $strTargetComputer)
#ClusterName
$objInstance.AddProperty("$MPElement[Name='Microsoft.Windows.Server.ClusterSharedVolumeMonitoring.Cluster.Base']/ClusterName$", $strClusterName)
#DisplayName
$objInstance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", "Windows Nano Server Cluster (disk monitoring)")

if ($error.Count -eq 0)
{

$objDiscoveryData.AddInstance($objInstance)

if ($error.Count -eq 0)
{
$iResult = $SCRIPT_SUCCESS
}

}

return $iResult
}

Function Is_NanoServer
{
$ErrorActionPreference="SilentlyContinue"
$Error.Clear()
$IsNano = (Get-Item "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Server\ServerLevels").GetValue("NanoServer")
$error.Clear()
$IsNano = $IsNano -eq 1

return $IsNano

}

Function Check-OsVersion([bool]$useCim)
{
$result = $false
$OsVersion = $Windows2016VersionPrefix
$Filter = "ProductType != 1 and Version like '$OsVersion%'"
$IsNano = Is_NanoServer

if (-Not $IsNano)
{
return $result
}

$Errror.Clear()
$Os = WMIGetInstanceNoAbort -sNamespace $WMI_NAMESPACE -sClassName $WMI_OsCLASS -sFilter $Filter -useCim $useCim
$result = ($null -ne $Os)

return $result
}

Function Get-ScriptName()
{
return "-- Cluster Shared Volumes Seed Discovery Script -- Version: $SCRIPT_VERSION"
}
################################################################
##Common Functions
################################################################
$CIM_ERROR_INVALIDCLASS = 2147749902
$CIM_ERROR_INVALIDNAMESPACE = 2147749904
$WMI_ERROR_INVALIDCLASS = -2147217392
$WMI_ERROR_INVALIDNAMESPACE = -2147217394
$WMI_CLUSTER_RESOURCE_TO_DISKPARTITION_CLASS = "MSCluster_ResourceToDiskPartition"
$WMI_MSCLUSTER_RESOURCE_CLASS = "MSCluster_Resource"
$WMI_CLUSTER_SHARED_VOLUME_TO_PARTITION_ASSOCIATOR_CLASS = "MSCluster_ClusterSharedVolumeToPartition"
$WMI_CLUSTER_SHARED_VOLUME_TO_RESOURCE_ASSOCIATOR_CLASS = "MSCluster_ClusterSharedVolumeToResource"
$WMI_ASSOCIATOR_DELIMITER = "="
$WMI_ASSOCIATOR_TRIMSYMBOL = """"
$WMI_ESCAPE_QUOTESYMBOL = "\"""
$WMI_SINGLE_QUOTESYMBOL = "'"
$WMI_ESCAPE_SINGLE_QUOTESYMBOL = "\'"
$WMI_ESCAPE_BACKSLASH_SYMBOL = "\\"

Function Check-WmiExceptions($Exception,[bool]$UseCim)
{
$result = $false

if ($true -eq $UseCim)
{
$result = Check-CimException -Exception $Exception
}
else
{
$result = Check-WmiException -Exception $Exception
}

return $result
}

Function Check-WmiException ($Exception)
{
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$error.Clear()

$bresult = $false

if ($null -eq $Exception)
{
return $bresult
}

$type = $Exception.GetType()

#Invalid ClassName or NameSpace
if([System.Management.ManagementException] -eq $type)
{
$ErrorCode = $Exception.ErrorCode.value__
if ($WMI_ERROR_INVALIDCLASS -eq $ErrorCode -or $WMI_ERROR_INVALIDNAMESPACE -eq $ErrorCode)
{
$bresult = $true
}
}

return $bresult

}

Function Check-CimException ($Exception)
{
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$error.Clear()

$bresult = $false

if ($null -eq $Exception)
{
return $bresult
}

$type = $Exception.GetType()
$error.Clear()
$WmiExcept = [Microsoft.Management.Infrastructure.CimException] -eq $type
if ($error.Count -ne 0)
{
$error.Clear()
return $bresult
}
#Invalid ClassName or NameSpace
if($WmiExcept)
{
$ErrorCode = $Exception.ErrorData.Error_code
if ($CIM_ERROR_INVALIDCLASS -eq $ErrorCode -or $CIM_ERROR_INVALIDNAMESPACE -eq $ErrorCode)
{
$bresult = $true
}
}

return $bresult

}

Function Convert-ToBoolean([string] $sBool)
{
[bool] $result = $false
[bool] $iresult = $false

if ($false -eq [string]::IsNullOrEmpty($sBool) )
{
$result = $sBool.Equals("true",[System.StringComparison]::InvariantCultureIgnoreCase)
$iresult = $sBool.Equals("1",[System.StringComparison]::InvariantCultureIgnoreCase)
$result = $result -or $iresult
}

return $result
}


Function CheckCimModule()
{
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$error.Clear()

$retval = $false
$cim = Get-Module -Name CimCmdlets

########Check for powershell 1.0
if ($error.Count -ne 0)
{
$type = $error[0].Exception.GetType()
if ([System.Management.Automation.CommandNotFoundException] -eq $type)
{
return $retval
}

$error.Clear()
}

if ($null -eq $cim)
{
Import-Module CimCmdLets
if ($error.Count -eq 0)
{
$retval = $true
}

$error.Clear()
}
else
{
$retval = $true
}

return $retval
}

function CheckCmdLets()
{
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$error.Clear()

$retval = $false
$objSWbemObjectSet =$null

if (CheckCimModule)
{
Load-CimModules
try
{
$cimSessionOption = New-CimSessionOption -Protocol DCOM
$cimsession = New-CimSession -SessionOption $cimSessionOption
$objSWbemObjectSet = Get-CimInstance -CimSession $cimsession -Class Win32_OperatingSystem -ErrorAction Stop
}
catch
{
$objSWbemObjectSet = Get-WMIObject -Class Win32_OperatingSystem -ErrorAction Stop
}
Finally
{
Get-CimSession | Remove-CimSession
$cimsession =$null
$cimSessionOption = $null
}

if ($error.Count -eq 0)
{
$retval = $true
}
}

$error.Clear()
return $retval;
}

Function Get-ClusterNameFromRegistry
{
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$error.Clear()
$ClusterPath = "HKLM:\Cluster"
$key = Get-ItemProperty -Path $ClusterPath -Name "ClusterName"
$result = [string]::Empty

if ($key -ne $null)
{
$result = $key.ClusterName
}

$error.Clear()
return $result

}

Function Get-ClusterName ($useCim)
{
$ClusterName = Get-ClusterNameFromRegistry

If (-Not [string]::IsNullOrEmpty($ClusterName) )
{
return $ClusterName
}

$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$error.Clear()
$WMI_MSCLUSTER_NAMESPACE_Local = "root\MSCluster"

if($useCIM)
{

Load-CimModules
try
{
$cimSessionOption = New-CimSessionOption -Protocol DCOM
$cimsession = New-CimSession -SessionOption $cimSessionOption
$Clusters = Get-CimInstance -CimSession $cimsession -ClassName MSCluster_Cluster -NameSpace $WMI_MSCLUSTER_NAMESPACE_Local
}
catch
{
$Clusters = Get-WMIObject -ClassName MSCluster_Cluster -NameSpace $WMI_MSCLUSTER_NAMESPACE_Local
}
Finally
{
Get-CimSession | Remove-CimSession
$cimsession =$null
$cimSessionOption = $null
}

if ($error.Count -ne 0)
{
return $ClusterName
}

foreach ($Cluster in $Clusters)
{
$ClusterName = $Cluster.Name
break
}
}else
{
$Clusters = Get-WmiObject -Class MSCluster_Cluster -NameSpace $WMI_MSCLUSTER_NAMESPACE_Local
if ($error.Count -ne 0)
{
return $ClusterName
}

foreach ($Cluster in $Clusters)
{
$ClusterName = $Cluster.Name
break
}
}

$error.Clear()

return $ClusterName

}


Function Get-ComputerName([string]$strTargetComputer)
{
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$error.Clear()
$strTargetComputerShortName = $strTargetComputer

if([string]::IsNullOrEmpty($strTargetComputerShortName))
{
return [string]::Empty
}

$index = $strTargetComputer.IndexOf(".")

if ( $index -gt 0)
{
$strTargetComputerShortName = $strTargetComputer.Substring(0, $index)
}

return $strTargetComputerShortName
}

Function LogScriptEvent($LogType,$EventId,$EventLevel,$Message,$objMomScriptAPI)
{
$ErrorActionPreference = 'SilentlyContinue'
$error.Clear()

$LogScriptName = Get-ScriptName
if ( 0 -eq $LogType)
{
if ($null -eq $objMomScriptAPI)
{
return
}

$objMomScriptAPI.LogScriptEvent($LogScriptName,$EventId,$EventLevel,$Message)
}
}

Function WMIGetAssociatorInstanceNoAbort
{
param (
[string]$sAssociatorName,
[string]$sWmiAssociatorName,
$oWmiInstance,
[bool] $useCim
)

$Error.Clear()
if ($true -eq $useCim)
{
Load-CimModules
try
{
$cimSessionOption = New-CimSessionOption -Protocol DCOM
$cimsession = New-CimSession -SessionOption $cimSessionOption
$oInstance = Get-CimAssociatedInstance -CimSession $cimsession -InputObject $oWmiInstance -Association $sAssociatorName -ErrorAction SilentlyContinue
}
catch
{
if($false -eq [string]::IsNullOrEmpty($oWmiInstance))
{
$ErrorActionPreference = 'SilentlyContinue'
$oInstance = $oWmiInstance.GetRelated($sWmiAssociatorName)
}
else
{
$oInstance = $null
}
}
Finally
{
Get-CimSession | Remove-CimSession
$cimsession =$null
$cimSessionOption = $null
}
}
else
{

if($false -eq [string]::IsNullOrEmpty($oWmiInstance))
{
$ErrorActionPreference = 'SilentlyContinue'
$oInstance = $oWmiInstance.GetRelated($sWmiAssociatorName)
}
else
{
$oInstance = $null
}
}

return $oInstance
}

Function WMIGetInstanceNoAbort
{
param (
[string]$sNamespace,
[string]$sClassName,
[string]$sFilter,
[bool] $useCim
)

if ($true -eq $useCim)
{
if([string]::IsNullOrEmpty($sFilter))
{
Load-CimModules
try
{
$cimSessionOption = New-CimSessionOption -Protocol DCOM
$cimsession = New-CimSession -SessionOption $cimSessionOption
$oInstance = Get-CimInstance -CimSession $cimsession -Namespace $sNamespace -ClassName $sClassName -ErrorAction SilentlyContinue
}
catch
{
$oInstance = Get-WMIObject -Namespace $sNamespace -ClassName $sClassName -ErrorAction SilentlyContinue
}
Finally
{
Get-CimSession | Remove-CimSession
$cimsession =$null
$cimSessionOption = $null
}
}
else
{
Load-CimModules
try
{
$cimSessionOption = New-CimSessionOption -Protocol DCOM
$cimsession = New-CimSession -SessionOption $cimSessionOption
$oInstance = Get-CimInstance -CimSession $cimsession -Namespace $sNamespace -ClassName $sClassName -Filter $sFilter -ErrorAction SilentlyContinue
}
catch
{
$oInstance = Get-WMIObject -Namespace $sNamespace -ClassName $sClassName -Filter $sFilter -ErrorAction SilentlyContinue
}
Finally
{
Get-CimSession | Remove-CimSession
$cimsession =$null
$cimSessionOption = $null
}
}
}
else
{
if([string]::IsNullOrEmpty($sFilter))
{

$oInstance = Get-WmiObject -Class $sClassName -Namespace $sNamespace -ErrorAction SilentlyContinue
}
else
{
$oInstance = Get-WmiObject -Class $sClassName -Namespace $sNamespace -Filter $sFilter -ErrorAction SilentlyContinue
}
}

return $oInstance
}

Function Throw-ScriptError([string]$Message)
{
throw $Message
exit
}


Function Get-CSVResource([string]$VolumeId,[hashtable]$VolumeToResource)
{
if ($null -eq $VolumeToResource -or [string]::IsNullOrEmpty($VolumeId))
{
return $null
}

$CsvResource = $VolumeToResource[$VolumeId]

return $CsvResource
}

Function Get-CSVPartition([string]$VolumeId,[hashtable]$VolumeToPartition)
{
if ($null -eq $VolumeToPartition -or [string]::IsNullOrEmpty($VolumeId))
{
return $null
}

$CsvPartition = $VolumeToPartition[$VolumeId]

return $CsvPartition
}

Function Get-ResourceNameToVolumeTable([bool]$useCim,[hashtable]$ResourceToVolume)
{
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$error.Clear()

if ($null -eq $ResourceToVolume)
{
return $false
}

$ResourceToVolumes = WMIGetInstanceNoAbort -sNamespace $WMI_MSCLUSTER_NAMESPACE -sClassName $WMI_CLUSTER_RESOURCE_TO_DISKPARTITION_CLASS -sFilter $null -useCim $useCim

if ($error.Count -ne 0)
{
return $false
}

foreach($Res in $ResourceToVolumes)
{
if($true -eq $useCim)
{
$ResourceName = $Res.GroupComponent.Name
$VolumeId = $Res.PartComponent.Path
}
else
{
$ResourceName = Get-WmiAssociatorId -ObjectId $Res.GroupComponent
$VolumeId = Get-WmiAssociatorId -ObjectId $Res.PartComponent
}

if ($false -eq [string]::IsNullOrEmpty($ResourceName))
{
$Volumes = $ResourceToVolume[$ResourceName]
if($null -eq $Volumes)
{
$Volumes = @()
}

$Volumes += $VolumeId
$ResourceToVolume[$ResourceName] = $Volumes
}
}

return $true

}

Function Get-VolumeToResourceTable([bool]$useCim,[hashtable]$VolumeToResource)
{
if ($null -eq $VolumeToResource)
{
return $false
}

$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$error.Clear()

$Filter = "ResourceClass = 1 and IsClusterSharedVolume = TRUE"
$ResourceNameToVolume = @{}

$Result = Get-ResourceNameToVolumeTable -useCim $useCim -ResourceToVolume $ResourceNameToVolume

if ($false -eq $Result)
{
return $false
}

$Filter = "ResourceClass = 1 and IsClusterSharedVolume = TRUE"
$Resources = WMIGetInstanceNoAbort -sNamespace $WMI_MSCLUSTER_NAMESPACE -sClassName $WMI_MSCLUSTER_RESOURCE_CLASS -sFilter $Filter -useCim $useCim

if ($error.Count -ne 0)
{
return $false
}

foreach($Resource in $Resources)
{
$ResName = $Resource.Name
if([string]::IsNullOrEmpty($ResName) )
{
continue
}

$Volumes = $ResourceNameToVolume[$ResName]
foreach($Volumeid in $Volumes)
{
$VolumeToResource[$VolumeId] = $Resource
}


}

return $true
}

Function Get-VolumeToPartitionTable([bool]$useCim,[hashtable]$VolumeToPartition)
{
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$error.Clear()

if ($null -eq $VolumeToPartition)
{
return $false
}


$Partitions = WMIGetInstanceNoAbort -sNamespace $WMI_MSCLUSTER_NAMESPACE -sClassName "MSCluster_DiskPartition" -sFilter $null -useCim $useCim

if ($error.Count -ne 0)
{
return $false
}

foreach ($Partition in $Partitions)
{
$VolumeToPartition[$Partition.Path] = $Partition
}


return $true

}

Function Get-ResourceNameToResourceTable([bool]$useCim,[hashtable]$NameToResource,[string]$Filter)
{
$ErrorActionPreference = 'SilentlyContinue' # Scoped only to function
$error.Clear()

if ($null -eq $NameToResource)
{
return $false
}


$Resources = WMIGetInstanceNoAbort -sNamespace $WMI_MSCLUSTER_NAMESPACE -sClassName "MSCluster_Resource" -sFilter $Filter -useCim $useCim

if ($error.Count -ne 0)
{
return $false
}

foreach ($Resource in $Resources)
{
$NameToResource[$Resource.Name] = $Resource
}


return $true

}

Function Get-VolumeTables([bool]$useCim,[hashtable]$VolumeToResource,[hashtable]$VolumeToPartition,$objClusterSharedVolumes)
{
$Result = Get-VolumeToResourceTable -useCim $useCim -VolumeToResource $VolumeToResource
if ($false -eq $Result)
{
$Result = Get-CSVolIdToResource -useCim $useCim -VolumeToResource $VolumeToResource -objClusterSharedVolumes $objClusterSharedVolumes
if ($false -eq $Result)
{
return $Result
}

}

$Result = Get-VolumeToPartitionTable -useCim $useCim -VolumeToPartition $VolumeToPartition

return $Result

}

Function Get-CSVolIdToResource([bool]$useCim,[hashtable]$VolumeToResource,$objClusterSharedVolumes)
{
if ( $null -eq $VolumeToResource)
{
return $false
}

$CSV = @{}
$NameToResource = @{}
$Filter = " ResourceClass = 1 and IsClusterSharedVolume = TRUE"

$Result = Get-ResourceNameToResourceTable -useCim $useCim -NameToResource $NameToResource -Filter $Filter
if ($false -eq $Result)
{
return $Result
}

$Volumes = WMIGetInstanceNoAbort -sNamespace $WMI_MSCLUSTER_NAMESPACE -sClassName $WMI_CLUSTER_SHARED_VOLUME_TO_RESOURCE_ASSOCIATOR_CLASS -sFilter $null -useCim $useCim
if ($error.Count -ne 0)
{
return $false
}

foreach($objCSV in $objClusterSharedVolumes)
{
if ([string]::IsNullOrEmpty($objCSV.Name))
{
continue
}

$CSV[$objCSV.Name] = $objCSV.VolumeName
}

foreach($Volume in $Volumes)
{
if($true -eq $useCim)
{
$CsvName = $Volume.GroupComponent.Name
$ResName = $Volume.PartComponent.Name
}
else
{
$CsvName = Get-WmiAssociatorId -ObjectId $Volume.GroupComponent
$ResName = Get-WmiAssociatorId -ObjectId $Volume.PartComponent
}

if ([string]::IsNullOrEmpty($CsvName) -or [string]::IsNullOrEmpty($ResName))
{
continue
}

$VolId = $CSV[$CsvName]
$Resource = $NameToResource[$ResName]
$VolumeToResource[$VolId] = $Resource
}

return $true
}

Function Get-WmiAssociatorId([string]$ObjectId)
{
if([string]::IsNullOrEmpty($ObjectId))
{
return [string]::Empty
}

$Index = $ObjectId.IndexOf($WMI_ASSOCIATOR_DELIMITER)

if ($Index -lt 3 -or $Index -eq ($ObjectId.Length - $WMI_ASSOCIATOR_DELIMITER.Length ))
{
return [string]::Empty
}

$Id = $ObjectId.Substring($Index + $WMI_ASSOCIATOR_DELIMITER.Length).Trim($WMI_ASSOCIATOR_TRIMSYMBOL)
$Id = Convert-WMIStringToString -WmiString $Id

return $Id
}

Function Convert-WMIStringToString([string]$WmiString)
{
$rString = ( ($WmiString -replace("\\\\","\")) -replace("\\'",$WMI_SINGLE_QUOTESYMBOL) ) -replace ("\\""",$WMI_ASSOCIATOR_TRIMSYMBO)
return $rString
}

Function Convert-StringToWmiString([string]$sString)
{
$rString = ( ($sString -replace($WMI_ESCAPE_BACKSLASH_SYMBOL,$WMI_ESCAPE_BACKSLASH_SYMBOL)) -replace($WMI_SINGLE_QUOTESYMBOL,$WMI_ESCAPE_SINGLE_QUOTESYMBOL) ) -replace ($WMI_ASSOCIATOR_TRIMSYMBOL,$WMI_ESCAPE_QUOTESYMBOL)
return $rString
}

Function Load-CimModules
{
$error.Clear()

$CimModule = Get-Module CimCmdlets

if ($null -eq $CimModule)
{
Import-Module CimCmdlets
$error.Clear()
}
}

Main

</PowerShellScriptBody>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
</DataSource>
</MemberModules>
<Composition>
<Node ID="Scheduler"/>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.Discovery.Data</OutputType>
</DataSourceModuleType>