Microsoft.SystemCenter.OperationsManager.Storage.SubSystem.DiagnoseDSType (DataSourceModuleType)

Element properties:

TypeDataSourceModuleType
IsolationAny
AccessibilityInternal
RunAsSystem.PrivilegedMonitoringAccount
OutputTypeSystem.PropertyBagData

Member Modules:

ID Module Type TypeId RunAs 
Scheduler DataSource System.Scheduler Default
Script ProbeAction Microsoft.Windows.PowerShellPropertyBagProbe Default

Overrideable Parameters:

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

Source Code:

<DataSourceModuleType ID="Microsoft.SystemCenter.OperationsManager.Storage.SubSystem.DiagnoseDSType" Accessibility="Internal" Batching="false" RunAs="System!System.PrivilegedMonitoringAccount">
<Configuration>
<IncludeSchemaTypes>
<SchemaType>Windows!Microsoft.Windows.PowerShellSchema</SchemaType>
<SchemaType>System!System.ExpressionEvaluatorSchema</SchemaType>
</IncludeSchemaTypes>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="VMMServerName" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="StorageObjectUniqueId" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="StorageObjectOMClassInstanceId" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" maxOccurs="1" name="TimeoutSeconds" type="xsd:integer"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="IntervalSeconds" type="xsd:integer"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="SyncTime" type="xsd:string"/>
</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="Scheduler" TypeID="System!System.Scheduler">
<Scheduler>
<SimpleReccuringSchedule>
<Interval>$Config/IntervalSeconds$</Interval>
<SyncTime>$Config/SyncTime$</SyncTime>
</SimpleReccuringSchedule>
<ExcludeDates/>
</Scheduler>
</DataSource>
<ProbeAction ID="Script" TypeID="Windows!Microsoft.Windows.PowerShellPropertyBagProbe">
<ScriptName>DiagnoseRuleScript.ps1</ScriptName>
<ScriptBody><Script># Creates sets of property bag data with File share to it's VHD subscription percentage
# Script parameters
# - $vmmServerName - VMM server name
# - $domain,$username,$pass - VMM Server Connection Account
# - $storageObjectUniqueId - UniqueId property of a given storage object
# - $storageObjectOMClassInstanceId - target storage object's class instance Id (OM)
# - Sample usage - .\DiagnoseRuleScript.ps1 -vmmServerName vmvmmServerName -domain redmond -username asttest -pass &lt;asttest_password&gt; -storageObjectUniqueId "{30fe9473-f681-482e-9373-44a46871219a}:SS" -storageObjectOMClassInstanceId "{B5DCAC09-20E9-B9C6-1FBF-B7841F629F06}"

param( [string] $vmmServerName, [string] $domain, [string] $username, [string] $pass, [string] $storageObjectUniqueId, [string] $storageObjectOMClassInstanceId)

#Storage Monitoring Event Ids
$GenericInformationEvent = 8700;
$GenericWarningEvent = 8701;
$GenericFailureEvent = 8702;
$CredentialNullCode = 8702;

$errorActionPreference = 'Stop'

$momAPI = New-Object -comObject 'MOM.ScriptAPI'

$errEvent = [System.Diagnostics.EventLogEntryType]::Error;
$infoEvent = [System.Diagnostics.EventLogEntryType]::Information;
$warningEvent = [System.Diagnostics.EventLogEntryType]::Warning;

#Alert Resolution States
$ResolutionStateClose = 255;
$ResolutionStateActive = 0;

$script:traceMsg = "";

#Adds tracemessage to $Script
Function AddTraceMessage
{
param($message)
$timeStamp = (get-date -format "HH:mm:ss:fff");
$script:traceMsg = $script:traceMsg + "`n[" + $timeStamp + "] " + $message;
}

Function CloseAlert
{
param($faultId)

Try
{
$FaultIdpatternToLookForInAlertContext = ("*" + $faultId +":" + $storageObjectUniqueId + "*");

AddTraceMessage -message "Searching OM Alert with this pattern: `n $FaultIdpatternToLookForInAlertContext"

$alert = (Get-SCOMAlert) | Where-Object {($_.Context -like $FaultIdpatternToLookForInAlertContext)}

if($alert -ne $null)
{
$alertName = $alert[0].Name;
AddTraceMessage -message ("Alert found. Name = " + $alertName)
Set-SCOMAlert -Alert $alert -ResolutionState $ResolutionStateClose
AddTraceMessage -message "Alert is closed."
}
else
{
AddTraceMessage -message "Could not find OM Alert with CompositeId = $faultId +":" + $storageObjectUniqueId"
}
}
Catch
{
$momAPI.LogScriptEvent("DiagnoseRuleScript.ps1", $GenericWarningEvent, 0, "Failed to close alert, please close the alert manually once the recommended action for the alert is taken. Exception message: " + $_.Exception.Message);
}
}

Try
{
$error.Clear();

AddTraceMessage -message "Storage monitoring script DiagnoseRuleScript.ps1 started."

AddTraceMessage -message "vmmServerName = $vmmServerName `ndomain = $domain`nusername = $username`nstorageObjectUniqueId=$storageObjectUniqueId`nstorageObjectOMClassInstanceId=$storageObjectOMClassInstanceId"

#Import VMM commands
$vmmModule = get-module -name "virtualmachinemanager"
if ($vmmModule -eq $null)
{
$modulePath = get-itemproperty -path "hklm:\software\microsoft\microsoft system center virtual machine manager administrator console\Setup";
Import-Module ($modulePath.InstallPath + "bin\psModules\virtualmachinemanager\virtualmachinemanager.psd1") | Out-Null
}

#Import OperationsManager commands
$omModule = get-module -name "OperationsManager"
if ($omModule -eq $null)
{
$SCOMPowerShellKey = "HKLM:\SOFTWARE\Microsoft\System Center Operations Manager\12\Setup\Powershell\V2"
$SCOMModulePath = Join-Path (Get-ItemProperty $SCOMPowerShellKey).InstallDirectory "OperationsManager"
Import-module $SCOMModulePath | Out-Null
}

#Connect to server
$vmmServer = Get-SCVMMServer -ComputerName localhost
AddTraceMessage -message "Got VMM server connection."

AddTraceMessage -message "Getting OM management server to connect to."

$mg = Get-SCOpsMgrConnection -Connect -VMMServer $vmmServer
if($mg -ne $null)
{
$managementServerName = $mg.OpsMgrServerName;
}
else
{
Throw [System.NullReferenceException] "Failed to connect get OM MG connection. This is fatal error, script will fail.";
}


AddTraceMessage -message "Connecting to $managementServerName OM management server."

New-SCManagementGroupConnection -ComputerName $managementServerName

AddTraceMessage -message "Connected to $managementServerName SDK. Now getting target class Instance"

# Get MonitoringObjectId in Guid format
$storageObjectId = New-Object -TypeName System.Guid -ArgumentList $storageObjectOMClassInstanceId

# Get OM MonitoringObject
$scomMonitoringObject = Get-SCOMMonitoringObject -Id $storageObjectId

$storageObject = Get-StorageSubsystem -UniqueId $storageObjectUniqueId

$results = Invoke-CimMethod -InputObject $storageObject -Method Diagnose

$newAlertsNeeded = @{}

if($results -ne $null)
{
$diagnoseResultsCount = $results.DiagnoseResults.Count
AddTraceMessage -message "Number of storage Diagnostics results found = $diagnoseResultsCount";
}


foreach($diagnosticsResult in $results.DiagnoseResults)
{
$storageFaultId = $diagnosticsResult.FaultId

# it is very unlikely that we will have result with a null or empty fault id string,
# but a safe check because this script closes all alerts based on fault id pattern, and in case of empty faultid string it may end up closing all active OM alerts for this object
if([string]::IsNullOrEmpty($storageFaultId))
{
AddTraceMessage -message "Null or empty storageFaultId in the Diagnostics Result. Skipping this fault";
continue
}

AddTraceMessage -message "An existing fault found on storage object $storageObjectUniqueId : $storageFaultId";

# Check if there are SCOM alerts for this fault Id
$FaultIdpatternToLookForInAlertContext = ("*" + $diagnosticsResult.FaultId +":" + $storageObjectUniqueId + "*");

AddTraceMessage -message "Searching OM Alert with this pattern: `n $FaultIdpatternToLookForInAlertContext"

$omAlertsForStorageFault = (Get-SCOMAlert -Instance $scomMonitoringObject) | Where-Object {$_.Context -like $FaultIdpatternToLookForInAlertContext}
if($omAlertsForStorageFault.Count -ne 0) #Alert already present
{
AddTraceMessage -message "No need to generate an alert for fault id $storageFaultId as there is already an alert generated for this fault Id."
}
else
{
# Delta between faults in Diagnose() results that are not in OMAlerts
AddTraceMessage -message "No alert found for fault id storageFaultId. Adding this fault Id to the list of new alerts to be generated."
$newAlertsNeeded.Add($diagnosticsResult.FaultId, $diagnosticsResult);
}
}

if($newAlertsNeeded -ne $null)
{
$numberOfNewAlerts = $newAlertsNeeded.Count;
AddTraceMessage -message "Number of alerts to be generated = $numberOfNewAlerts"
}

#Generate new alerts for new faults
foreach($newAlertsNeededItem in $newAlertsNeeded.GetEnumerator())
{
$faultIdForNewAlert = $newAlertsNeededItem.Key;
$diagnosticsResultForNewAlert = $newAlertsNeededItem.Value;

#Create new alert property bag data
$propertyBag = $momAPI.CreatePropertyBag()
$propertyBag.AddValue("FaultId", $diagnosticsResultForNewAlert.FaultId);
$propertyBag.AddValue("FaultingObjectDescription", $diagnosticsResultForNewAlert.FaultingObjectDescription);
$propertyBag.AddValue("Reason", $diagnosticsResultForNewAlert.Reason);
$propertyBag.AddValue("RecommendedActions", $diagnosticsResultForNewAlert.RecommendedActions -join "`n");
$propertyBag.AddValue("SourceUniqueId", $storageObjectUniqueId);

$perceivedSeverity = $diagnosticsResultForNewAlert.PerceivedSeverity;
$propertyBag.AddValue("PerceivedSeverity", $perceivedSeverity);

#OM Alert severity
$alertSeverity = 1; # Default for OM would be warning
if($perceivedSeverity -eq 2)
{
$alertSeverity = 0 #Information
}
elseif(($perceivedSeverity -eq 3) -or ($perceivedSeverity -eq 4))
{
$alertSeverity = 1 #Warning
}
elseif(($perceivedSeverity -ge 5))
{
$alertSeverity = 2 #Warning
}

$propertyBag.AddValue("OM Alert Severity", $alertSeverity);

$propertyBag.AddValue("CompositeAlertId", $diagnosticsResultForNewAlert.FaultId + ":" + $storageObjectUniqueId);

$propertyBag
}

Try
{
# Get All active storage alerts
$allOMAlerts = Get-SCOMAlert -Instance $scomMonitoringObject | where-object {($_.Context -like '*FaultId*') -and ($_.ResolutionState -eq $ResolutionStateActive)}

# Get list of all FaultIds from all active storage alerts
$allOMAlertsFaultIds = ($allOMAlerts | ForEach-Object { $context = [xml]$_.Context; ($context.DataItem.Property | where {$_.Name -eq "FaultId"}).InnerText})

AddTraceMessage -message "Found alerts with storage faults on this object.`nAlert exist for these FaultIds = $allOMAlertsFaultIds"

$allDiagnosticcsResultsFaults = $results.DiagnoseResults.FaultId
AddTraceMessage -message "Diagnose() found these faults are still present = $allDiagnosticcsResultsFaults"

# Delta between OMAlerts that are not in the Diagnose() results anymore
$closeAlertsForTheseFaults = $allOMAlertsFaultIds | ?{$results.DiagnoseResults.FaultId -notcontains $_}

$numberOfStaleAlerts = $closeAlertsForTheseFaults.Count
AddTraceMessage -message "Number of alerts to be closed = $numberOfStaleAlerts"

# Close Alerts
foreach($faultIdToBeClosed in $closeAlertsForTheseFaults)
{
CloseAlert -faultId $faultIdToBeClosed
}
}
Catch
{
$momAPI.LogScriptEvent("DiagnoseRuleScript.ps1", $GenericWarningEvent, 0, "Failed to close active storage alerts for closed storage faults, please close the alert manually once the recommended actions for any such alerts are taken. Exception message: " + $_.Exception.Message);
}

AddTraceMessage -message "Storage monitoring script DiagnoseRuleScript.ps1 completed."
}
Catch
{
AddTraceMessage -message $_.Exception.Message
}
Finally
{
if($vmmServer -ne $null)
{
$vmmServer.Disconnect();
}

if ($error -ne $null -and $error.Count -gt 0 -and $error[0] -ne $null)
{
$momAPI.LogScriptEvent("DiagnoseRuleScript.ps1", $GenericFailureEvent, 1, $error[0].ToString());
}

if ($script:traceMsg -ne $null)
{
$momAPI.LogScriptEvent("DiagnoseRuleScript.ps1", $GenericInformationEvent, 0, $script:traceMsg);
}
}</Script></ScriptBody>
<Parameters>
<Parameter>
<Name>vmmServerName</Name>
<Value>$Config/VMMServerName$</Value>
</Parameter>
<Parameter>
<Name>domain</Name>
<Value>$RunAs[Name="PROV2Library!Microsoft.SystemCenter.VirtualMachineManager.2012.VMMServerConnectionRunAsProfile"]/Domain$</Value>
</Parameter>
<Parameter>
<Name>username</Name>
<Value>$RunAs[Name="PROV2Library!Microsoft.SystemCenter.VirtualMachineManager.2012.VMMServerConnectionRunAsProfile"]/UserName$</Value>
</Parameter>
<Parameter>
<Name>pass</Name>
<Value>$RunAs[Name="PROV2Library!Microsoft.SystemCenter.VirtualMachineManager.2012.VMMServerConnectionRunAsProfile"]/Password$</Value>
</Parameter>
<Parameter>
<Name>storageObjectUniqueId</Name>
<Value>$Config/StorageObjectUniqueId$</Value>
</Parameter>
<Parameter>
<Name>storageObjectOMClassInstanceId</Name>
<Value>$Config/StorageObjectOMClassInstanceId$</Value>
</Parameter>
</Parameters>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
<StrictErrorHandling>true</StrictErrorHandling>
</ProbeAction>
</MemberModules>
<Composition>
<Node ID="Script">
<Node ID="Scheduler"/>
</Node>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.PropertyBagData</OutputType>
</DataSourceModuleType>