A Microsoft Windows Server Közvetlen tárolóhelyek riasztások lezárására vonatkozó írási művelete

Microsoft.Windows.Server.10.0.Storage.StorageSpacesDirect.CloseAlertsWriteAction (WriteActionModuleType)

A Közvetlen tárolóhelyek riasztások lezárására vonatkozó írási művelete.

Element properties:

TypeWriteActionModuleType
IsolationAny
AccessibilityInternal
RunAsSystem.PrivilegedMonitoringAccount
InputTypeSystem.BaseData

Member Modules:

ID Module Type TypeId RunAs 
CD ConditionDetection System.ExpressionFilter Default
WA WriteAction Microsoft.Windows.PowerShellWriteAction Default

Overrideable Parameters:

IDParameterTypeSelectorDisplay NameDescription
TimeoutSecondsint$Config/TimeoutSeconds$A szkript hibákkal kapcsolatos riasztások lezárására vonatkozó időtúllépése (mp)

Source Code:

<WriteActionModuleType ID="Microsoft.Windows.Server.10.0.Storage.StorageSpacesDirect.CloseAlertsWriteAction" Accessibility="Internal" Batching="true" RunAs="System!System.PrivilegedMonitoringAccount">
<Configuration>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="FaultId" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="StorageUniqueID" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="StorageObjectID" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="TargetId" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="DataType" type="xsd:string"/>
<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="0" name="RuleId1" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="0" name="RuleId2" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="0" name="RuleId3" type="xsd:string"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int"/>
</OverrideableParameters>
<ModuleImplementation>
<Composite>
<MemberModules>
<ConditionDetection ID="CD" TypeID="System!System.ExpressionFilter">
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="String">Property[@Name='DataType']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="String">List</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</ConditionDetection>
<WriteAction ID="WA" TypeID="Windows!Microsoft.Windows.PowerShellWriteAction">
<ScriptName>CloseAlerts.ps1</ScriptName>
<ScriptBody><Script>

param($faultIds, $storageObjectUniqueID, $storageObjectObjectID, $targetId,$EventType,$RuleId1,$RuleId2,$RuleId3)
$SCRIPT_NAME = "CloseAlerts.ps1"


#general variables
#-----------------
$errorActionPreference = 'Stop'

$errEvent = [System.Diagnostics.EventLogEntryType]::Error;
$infoEvent = [System.Diagnostics.EventLogEntryType]::Information;
$GenericInformationEvent = 8671;
$GenericFailureEvent = 8672;
$script:traceMsg = "";
$momAPI = New-Object -comObject 'MOM.ScriptAPI'

$ResolutionStateClose = 255;
$ResolutionStateActive = 0;

$AlertCriteria = "IsMonitorAlert = 'false' and ResolutionState = $ResolutionStateActive and CustomField1 = 'Fault' "

if ($false -eq [string]::IsNullOrEmpty($DebugMode))
{
$DebugMode = [string]::Equals("true",$DebugMode,[System.StringComparison]::OrdinalIgnoreCase)
}
else
{
$DebugMode = $false
}

Function AddTraceMessage
{
param($message)

$errorActionPreference = 'SilentlyContinue'
$timeStamp = (get-date -format "HH:mm:ss:fff");
$script:traceMsg = $script:traceMsg + "`n[" + $timeStamp + "] " + $message;
}

Function Get-Guid([string]$sguid)
{
if ([string]::IsNullOrEmpty($sguid))
{
return $null
}

$guid = [guid]::NewGuid()
if ($false -eq [guid]::TryParse($sguid,[ref] $guid))
{
return $null;
}

return $guid
}

Function Log-FinalDebugData([int]$FailureEvent,[int]$InformationEvent,$exception,[string]$SCRIPT_NAME,[string]$traceMsg,[bool]$DebugMode = $false,$message = [string]::Empty)
{
$ErrorActionPreference = "SilentlyContinue"

if ($null -ne $exception)
{
if ([string]::Empty -eq $message) {$message = "Error occured during script execution:"}
$momAPI.LogScriptEvent($SCRIPT_NAME, $FailureEvent, 1, "$message $($exception.Message)");
}

if ($script:traceMsg -ne $null -and $true -eq $DebugMode)
{
$momAPI.LogScriptEvent($SCRIPT_NAME,$InformationEvent, 0, $traceMsg);
}
}


Function Prepare-ScomConnection()
{
$ErrorActionPreference = "Stop"
$managementServerName = "localhost"

$result = $true
try
{
#Import-Module OperationsManager
$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"
[void](Import-module $SCOMModulePath)
}

AddTraceMessage -message "Connecting to $managementServerName OM management server."
New-SCManagementGroupConnection -ComputerName $managementServerName
AddTraceMessage -message "Connected to $managementServerName SDK. Now getting target class Instance"

}
catch
{
$result = $false
}

return $result
}

AddTraceMessage -message "Start on Management Server: $env:COMPUTERNAME"



#param($faultIds, $storageObjectUniqueID, $storageObjectObjectID, $targetId,$EventType,$RuleId1,$RuleId2,$RuleId3)

#ruleId1 - Generate Alert Rule
#ruleId2 - Refresh Alert Rule
#ruleId3 - Sync Alert Rule


$AlertRules = @(1..3)

Function ParseFaultIds
{
param([string]$inpt)

$result = @{}
if($true -eq [string]::IsNullOrEmpty($inpt))
{
return $result;
}

$separator = ","
$option = [System.StringSplitOptions]::RemoveEmptyEntries
$faults = $inpt.Split($separator, $option)
foreach($fault in $faults)
{
$faultId = Get-Guid -sguid $fault
if ($null -ne $faultId)
{
$result[$faultId] = 1
}
}

return $result
}

Function CloseAlerts
{
param($alerts)

$ErrorActionPreference = "Stop"

$alertsCount = $alerts.Count
if ($null -eq $alerts -or 0 -eq $alertsCount) {return}


Try
{
AddTraceMessage -message "Trying to close $alertsCount Alert(s)."
foreach($alert in $alerts)
{
$alert.ResolutionState = $ResolutionStateClose
if ($null -eq $alert.ManagementGroup.IsConnected) {continue;}
if ($false -eq $alert.ManagementGroup.IsConnected) {$alert.ManagementGroup.Reconnect();}
$alert.Update("Closed by S2D sync rule");
}

AddTraceMessage -message "All $alertsCount Alert(s) are closed."

}
Catch
{
AddTraceMessage -message $_.Exception.Message
}
}

Function Get-AlertRuleCriteria()
{
$ErrorActionPreference = "Stop"

$result = $AlertCriteria
$rules = @()

$rule1 = Get-Guid -sguid $RuleId1
$rule2 = Get-Guid -sguid $RuleId2
$rule3 = Get-Guid -sguid $RuleId3

if ($null -ne $rule1)
{$rule = "MonitoringRuleId='{0}'" -f $rule1 ; $rules += $rule; $AlertRules[0] = $rule1;}
else
{
$AlertRules[0] = $null
}

if ($null -ne $rule2)
{$rule = "MonitoringRuleId='{0}'" -f $rule2 ; $rules += $rule; $AlertRules[1] = $rule2;}
else
{
$AlertRules[1] = $null
}

if ($null -ne $rule3)
{$rule = "MonitoringRuleId='{0}'" -f $rule3 ; $rules += $rule; $AlertRules[2] = $rule3}
else
{
$AlertRules[2] = $null
}

if (0 -ne $rules.Length)
{
$result = "(" + ($rules -join " or " ) + ") and " + $result
}

$MonAlertCriteria = New-Object -TypeName "Microsoft.EnterpriseManagement.Monitoring.MonitoringAlertCriteria" -ArgumentList ($result)

return $MonAlertCriteria
}

Function Get-AlertsFromObject($mo,$criteria)
{
$ErrorActionPreference = "Stop"

if ($null -eq $mo -or $null -eq $criteria)
{
return $null
}

$mg = $mo.ManagementGroup

If ($null -eq $mg) {return $null;}

if ($false -eq $mg.IsConnected)
{
$mg.ReConnect()
}

return $mo.GetMonitoringAlerts($criteria)
}

Function Get-ActiveAlertForNonRule1($alerts)
{
#FaultId from Rule1
$RuleAlerts = @{}
$Rule2 = $AlertRules[1]
$Rule3 = $AlertRules[2]

if ($null -eq $Rule2 -and $null -eq $Rule3)
{
return $null
}

if ($null -eq $Rule2)
{
$newAlerts = $alerts | Where-Object { $_.RuleId -eq $Rule3}
}
else
{
if ($null -eq $Rule3)
{
$newAlerts = $alerts | Where-Object { $_.RuleId -eq $Rule2}
}
else
{
$newAlerts = $alerts | Where-Object { $_.RuleId -eq $Rule2 -or $_.RuleId -eq $Rule3}
}
}

return $newAlerts

}

Function Get-ActiveAlertForRule1($alerts)
{
#FaultId from Rule1
$RuleAlerts = @{}
$RuleId = $AlertRules[0]

if ($null -eq $alerts -or $null -eq $RuleId)
{
return $RuleAlerts
}

$Ralerts = $alerts | Where-Object { $_.RuleId -eq $RuleId}
if ($null -eq $Ralerts)
{
return $RuleAlerts
}

foreach($alert in $Ralerts)
{
$faultId = Get-FaultIdFromAlert -alert $alert
if ($null -eq $faultId) {continue;}

$RuleAlerts[$faultId] = 1
}

return $RuleAlerts

}

Function Get-DuplicateAlertsForClose($alerts)
{

if ($null -eq $alerts )
{
return $null
}

$alertsNonRule1 = Get-ActiveAlertForNonRule1 -alerts $alerts

#If null - nothing to close
if ($null -eq $alertsNonRule1) {return $null;}
$Rule1Faults = Get-ActiveAlertForRule1 -alerts $alerts

#If null - nothing to close
if ($null -eq $Rule1Faults -or 0 -eq $Rule1Faults.Count) {return $null;}

$newAlerts = @{}

foreach($alert in $alertsNonRule1)
{
$faultId = Get-FaultIdFromAlert -alert $alert
if ($null -eq $faultId) {continue;}
if ($true -eq $Rule1Faults.ContainsKey($faultId)) { $newAlerts[$alert] = 1;}
}

if (0 -eq $newAlerts.Count) {$newAlerts = $null;}

return $newAlerts;

}

Function Get-FaultIdFromAlert($alert)
{
$ErrorActionPreference = "SilentlyContinue"

if ($null -eq $alert)
{
return $null
}

$faultId = Get-Guid -sguid $alert.CustomField2
if ($null -ne $faultId) {return $faultId}

$error.Clear()
$context = [xml]$alert.Context
if (0 -ne $error.Count -or $null -eq $context)
{
$error.Clear()
return $null
}

$faultId = Get-Guid -sguid $context.SelectSingleNode("/DataItem/Property[@Name='FaultId']").InnerText

return $faultId
}

Function Get-ActiveAlerts($storageObjectId,[HashTable]$activefaults)
{
$ErrorActionPreference = "Stop"

$alerts = @{}
$result = $null

$scomMonitoringObject = Get-SCOMMonitoringObject -Id $storageObjectId
if ($null -eq $scomMonitoringObject){return $result}

$AlertsCriteria = Get-AlertRuleCriteria

#Get all active SCOM storage alerts from faults rules
$all_active_alerts = Get-AlertsFromObject -mo $scomMonitoringObject -criteria $AlertsCriteria


if ($null -eq $all_active_alerts)
{
return $result
}

$duplicateAlertsToClose = Get-DuplicateAlertsForClose -alerts $all_active_alerts

$IsAllAlerts = $false
if ($null -eq $activefaults -or 0 -eq $activefaults.Count)
{
$IsAllAlerts = $true
}


foreach($alert in $all_active_alerts)
{
$faultId = Get-FaultIdFromAlert -alert $alert
if ($null -ne $faultId -and ($true -eq $IsAllAlerts -or $false -eq $activefaults.ContainsKey($faultId)) )
{
$alerts[$alert] = 1

}
}

if ($null -ne $duplicateAlertsToClose)
{
foreach($alert in $duplicateAlertsToClose.Keys)
{
if ($null -eq $alert) {continue;}
if ($false -eq $alerts.ContainsKey($alert)) { $alerts[$alert] = 1;}
}
}

if (0 -ne $alerts.Count)
{
$result = @($alerts.Keys)
}

return $result
}

Function Check-ScriptArguments($storageObjectId)
{
$ErrorActionPreference = "SilentlyContinue"
$result = $false;

#in some cases CD module works incorrectly
if ([string]::IsNullOrEmpty($EventType) -or "List" -ne $EventType)
{
AddTraceMessage -message "Incorrect DataItem returned. Type is equal to [$EventType] instead of [List]"
return $false
}

$result = $true

return $result
}

Function Log-FinalData()
{
$ErrorActionPreference = "SilentlyContinue"

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

if ($script:traceMsg -ne $null)
{
$momAPI.LogScriptEvent($SCRIPT_NAME, $GenericInformationEvent, 0, $script:traceMsg);
}
}

Function Prepare-Environment($storageObjectId)
{
$ErrorActionPreference = "SilentlyContinue"

$result = Check-ScriptArguments -storageObjectId $storageObjectId
if ($false -eq $result) {return $result}
$result = Prepare-ScomConnection

return $result
}

Function Process-Faults($storageObjectId)
{
$ErrorActionPreference = "Stop"

try
{
$activeFaults = ParseFaultIds -inpt $faultIds
$alerts = Get-ActiveAlerts -storageObjectId $storageObjectId -activefaults $activeFaults
$AlertCount = $alerts.Count
AddTraceMessage -message "Number of active alerts = $AlertCount"

CloseAlerts -alerts $alerts
}
catch
{
AddTraceMessage -message $_.Exception.Message
}
finally
{
Log-FinalData
}

}

Function PrintTraceMessage
{
#if ($false -eq $DebugMode) { return;}

AddTraceMessage -message "Storage monitoring script CloseAlerts.ps1 started."
AddTraceMessage -message "TargeObjectId : $targetId"
AddTraceMessage -message "StorageObjectId : $storageObjectObjectID"
AddTraceMessage -message "storageObjectUniqueID : $storageObjectUniqueID"
AddTraceMessage -message "FaultId : $faultIds"
AddTraceMessage -message "ItemType : $EventType"

}

Function Main()
{
$ErrorActionPreference = "Stop"

PrintTraceMessage

$storageObjectId = Get-Guid -sguid $targetId

$result = Prepare-Environment -storageObjectId $storageObjectId

if ($false -eq $result)
{
Log-FinalData
return
}

Process-Faults -storageObjectId $storageObjectId

}

Main

</Script></ScriptBody>
<Parameters>
<Parameter>
<Name>faultIds</Name>
<Value>$Config/FaultId$</Value>
</Parameter>
<Parameter>
<Name>targetId</Name>
<Value>$Config/TargetId$</Value>
</Parameter>
<Parameter>
<Name>storageObjectUniqueID</Name>
<Value>$Config/StorageUniqueID$</Value>
</Parameter>
<Parameter>
<Name>storageObjectObjectID</Name>
<Value>$Config/StorageObjectID$</Value>
</Parameter>
<Parameter>
<Name>EventType</Name>
<Value>$Config/DataType$</Value>
</Parameter>
<Parameter>
<Name>RuleId1</Name>
<Value>$Config/RuleId1$</Value>
</Parameter>
<Parameter>
<Name>RuleId2</Name>
<Value>$Config/RuleId2$</Value>
</Parameter>
<Parameter>
<Name>RuleId3</Name>
<Value>$Config/RuleId3$</Value>
</Parameter>
</Parameters>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
</WriteAction>
</MemberModules>
<Composition>
<Node ID="WA">
<Node ID="CD"/>
</Node>
</Composition>
</Composite>
</ModuleImplementation>
<InputType>System!System.BaseData</InputType>
</WriteActionModuleType>