Veeam Hyper-V Cluster SDK Base Property Bag Datasource

Veeam.Virt.Extensions.HyperV.Module.VM.ClusterSDK.Base.PropertyBagProvider (DataSourceModuleType)

Element properties:

TypeDataSourceModuleType
IsolationAny
AccessibilityInternal
RunAsDefault
OutputTypeSystem.PropertyBagData

Member Modules:

ID Module Type TypeId RunAs 
DS DataSource Veeam.Virt.Extensions.HyperV.Module.TimedPowerShell.PropertyBagProvider Default

Overrideable Parameters:

IDParameterTypeSelector
IntervalSecondsint$Config/IntervalSeconds$
SyncTimestring$Config/SyncTime$
TimeoutSecondsint$Config/TimeoutSeconds$

Source Code:

<DataSourceModuleType ID="Veeam.Virt.Extensions.HyperV.Module.VM.ClusterSDK.Base.PropertyBagProvider" 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="SyncTime" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="TimeoutSeconds" type="xsd:integer"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int"/>
<OverrideableParameter ID="SyncTime" Selector="$Config/SyncTime$" ParameterType="string"/>
<OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int"/>
</OverrideableParameters>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<DataSource ID="DS" TypeID="Veeam.Virt.Extensions.HyperV.Module.TimedPowerShell.PropertyBagProvider">
<IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
<SyncTime>$Config/SyncTime$</SyncTime>
<ScriptName>ClusterPerf.ps1</ScriptName>
<ScriptBody><Script>$serverClassName = "Veeam.Virt.Extensions.HyperV.ServerRole";
$clusterClassName = "Veeam.Virt.Extensions.HyperV.Cluster";

[DateTime] $now = [DateTime]::UtcNow;
[DateTime] $before = $now.AddMinutes(-10);

$momApi = New-Object -ComObject "MOM.ScriptAPI";

$cr = new-object Microsoft.EnterpriseManagement.Configuration.MonitoringClassCriteria("Name='$serverClassName'");
$cpuMHzPerfCr = new-object Microsoft.EnterpriseManagement.Monitoring.MonitoringPerformanceDataCriteria("ObjectName='Hyper-V Hypervisor Logical Processor' AND CounterName='CPU Usage MHz'");
$memMBPerfCr = new-object Microsoft.EnterpriseManagement.Monitoring.MonitoringPerformanceDataCriteria("ObjectName='Memory' AND CounterName='Memory Used MB'");

function loadModule() {
$isLoaded = $false;
$Error.Clear();
Import-Module OperationsManager -ErrorAction:SilentlyContinue;
if ($Error.Count -ne 0)
{
$rkey = "HKLM:\SOFTWARE\Microsoft\System Center Operations Manager\12\Setup\Powershell\V2";
$rvalName = "InstallDirectory";
$rval = Get-ItemProperty -path:$rkey -name:$rvalName -ErrorAction:SilentlyContinue;
$modulePath = "";
if ($rval -ne $null)
{
$modulePath = $rval.InstallDirectory;
}
$Error.Clear();
Import-Module "$modulePath\OperationsManager" -ErrorAction:SilentlyContinue;
}

if ($Error.Count -eq 0)
{
$moduleInf = Get-Module | ? {$_.Name -eq "OperationsManager"};
if ($moduleInf -ne $null)
{
$isLoaded = $true;
}
}
return $isLoaded;
}

function getPerf($clusterObject) {
$bag = $momApi.CreatePropertyBag();
$bag.AddValue("Name", $clusterObject.Name);

[double] $totalCPU = 0;
[double] $totalMem = 0;
[double] $cpuUsage = 0;
[double] $memUsage = 0;

$partMonObject = $mg.GetPartialMonitoringObject($clusterObject.Id);
$hosts = $partMonObject.GetRelatedMonitoringObjects($clusterToHostRel);
foreach ($h in $hosts) {
$totCpuProp = $h.GetMonitoringProperties() | ? {$_.Name -eq "TotalCPUGHz"};
$totCpuValue = $h.GetMonitoringPropertyValue($totCpuProp);
$totalCPU += $totCpuValue;

$totMemProp = $h.GetMonitoringProperties() | ? {$_.Name -eq "MemoryGB"};
$totMemValue = $h.GetMonitoringPropertyValue($totMemProp);
$totalMem += $totMemValue;
}


$perfData = $partMonObject.GetMonitoringPerformanceData($cpuMHzPerfCr, $monClass, [Microsoft.EnterpriseManagement.Common.TraversalDepth]::Recursive);
if ($perfData.Count -ne 0) {
foreach ($pd in $perfData) {
$perfValues = $pd.GetValues($before, $now);
if ($perfValues.Count -gt 0) {
$lastValue = $perfValues[$perfValues.Count - 1];
$cpuUsage += $lastValue.SampleValue;
}
}
}

$perfData = $partMonObject.GetMonitoringPerformanceData($memMBPerfCr, $monClass, [Microsoft.EnterpriseManagement.Common.TraversalDepth]::Recursive);
if ($perfData.Count -ne 0) {
foreach ($pd in $perfData) {
$perfValues = $pd.GetValues($before, $now);
if ($perfValues.Count -gt 0) {
$lastValue = $perfValues[$perfValues.Count - 1];
$memUsage += $lastValue.SampleValue;
}
}
}

$resCPUPct = 0;
if ($totalCPU -gt 0) {
$resCPUPct = ($cpuUsage / ($totalCPU * 1000)) * 100;
}
$resMemPct = 0;
if ($totalMem -gt 0) {
$resMemPct = ($memUsage / ($totalMem * 1024)) * 100;
}

if ($resCPUPct -eq 0) {
$resCPUPct = -1;
}
if ($resMemPct -eq 0) {
$resMemPct = -1;
}

$bag.AddValue("CPUUsedPct", $resCPUPct.ToString("N2"));
$bag.AddValue("MemUsedPct", $resMemPct.ToString("N2"));
$bag;
}

function getClusters() {
$monCriteria = new-object Microsoft.EnterpriseManagement.Configuration.MonitoringClassCriteria("Name='$clusterClassName'");
$clusterClasses = $mg.GetMonitoringClasses($monCriteria);
if ($clusterClasses.Count -eq 1) {
$clusterClass = $clusterClasses[0];
$clObjects = $mg.GetMonitoringObjects($clusterClass);
return $clObjects;
}
return $null;
}

function emptyBag() {
$bag = $momApi.CreatePropertyBag();
$bag.AddValue("Name", "Undefined");
$bag.AddValue("CPUUsedPct", -1);
$bag.AddValue("MemUsedPct", -1);
$bag;
}

$moduleLoaded = loadModule;

if ($moduleLoaded) {
$mg = Get-SCOMManagementGroup;
$clusterToHostRel = $mg.GetMonitoringRelationshipClass("08120a55-63dd-b11b-cf4e-364b3ed32054");
$monClasses = $mg.GetMonitoringClasses($cr);
if ($monClasses.Count -eq 1) {
$monClass = $monClasses[0];
$c = getClusters;
if ($c -ne $null -and $c.Count -gt 0) {
$c | % {
getPerf $_;
}
}
else {
emptyBag;
}
}
else {
emptyBag;
}
}
else {
emptyBag;
}</Script></ScriptBody>
<SnapIns/>
<Parameters/>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
</DataSource>
</MemberModules>
<Composition>
<Node ID="DS"/>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.PropertyBagData</OutputType>
</DataSourceModuleType>