S2D: Źródło danych zdarzeń alertów o błędach usługi WMI
Microsoft.Windows.Server.10.0.Storage.StorageSpacesDirect.FaultWmiAlertEventDataSource (DataSourceModuleType)
Źródło danych zdarzeń alertów o błędach usługi WMI.
Element properties: Member Modules:
Overrideable Parameters:
Source Code: <DataSourceModuleType ID="Microsoft.Windows.Server.10.0.Storage.StorageSpacesDirect.FaultWmiAlertEventDataSource" Accessibility="Internal" RunAs="System!System.PrivilegedMonitoringAccount" Batching="false">
<Configuration>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="InstanceType" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="TargetInstanceUniqueID" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="TargetInstanceObjectID" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="ComputerName" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="PollInterval" type="xsd:integer"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="WQLQuery" 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" minOccurs="1" name="TimeoutSeconds" type="xsd:integer"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="0" name="VirtualDiskId" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="0" name="bagType" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="0" name="DebugMode" type="xsd:boolean"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="PollInterval" Selector="$Config/PollInterval$" ParameterType="int"/>
<OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int"/>
<OverrideableParameter ID="DebugMode" Selector="$Config/DebugMode$" ParameterType="bool"/>
</OverrideableParameters>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<DataSource ID="WmiEventProviderDS" TypeID="Windows!Microsoft.Windows.WmiEventProvider">
<NameSpace>\\$Config/ComputerName$\root\Microsoft\Windows\Storage</NameSpace>
<Query>$Config/WQLQuery$</Query>
<PollInterval>$Config/PollInterval$</PollInterval>
</DataSource>
<ProbeAction ID="PA" TypeID="Windows!Microsoft.Windows.PowerShellPropertyBagProbe">
<ScriptName>GetFaultsScript.ps1</ScriptName>
<ScriptBody><Script>
Param($TargetInstanceObjectID,$InstanceType, $SourceUniqueId, $SourceObjectId, $TargetId,$VirtualDiskId,$bagType)
$SCRIPT_NAME = "GetFaultsScript.ps1"
#general variables
#-----------------
$errorActionPreference = 'Stop'
$errEvent = [System.Diagnostics.EventLogEntryType]::Error;
$infoEvent = [System.Diagnostics.EventLogEntryType]::Information;
$GenericInformationEvent = 8671;
$GenericFailureEvent = 8672;
$DiscoveryGenericInformationEvent = 8861;
$DiscoveryGenericFailureEvent = 8862;
$script:traceMsg = "";
$ObjectNotFoundCode = -2146233087
$msft_namespace = "root\microsoft\windows\storage"
$cluster_namespace = "root\mscluster"
# Guid length for Virtual Disk
$guidLength = 38
$PadLength = 1 #Object Id ended with double quote
if ($false -eq [string]::IsNullOrEmpty($DebugMode))
{
$DebugMode = [string]::Equals("true",$DebugMode,[System.StringComparison]::OrdinalIgnoreCase)
}
else
{
$DebugMode = $false
}
$momAPI = New-Object -comObject 'MOM.ScriptAPI'
#Common Functions
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 GetDiskIdFilterFromVdObjectId([string]$ObjectId)
{
if ($true -eq [string]::IsNullOrEmpty($ObjectId))
{
return $null
}
$Length = $ObjectId.Length
#check guid length - 38 in {guid} format
$rGuidLength = $guidLength + $PadLength
if ($Length -lt $rGuidLength) {return $null;}
$sguid = $ObjectId.Substring($Length - $rGuidLength,$guidLength)
$guid = Get-Guid -sguid $sguid
if ($null -eq $guid) {return $null;}
return "DiskId='\\\\?\\Disk{$guid}'"
}
Function GetVolumesFromVd($vd)
{
$errorActionPreference = "Stop"
$Filter = GetDiskIdFilterFromVdObjectId -ObjectId $vd.ObjectId
if ($null -eq $Filter ) {return $null;}
$partitions = Get-CimInstance -ClassName "MSFT_Partition" -Namespace $msft_namespace -Filter $Filter | Where-Object {$_.AccessPaths -ne $null}
$volumes = @{}
foreach ($partition in $partitions)
{
$Volume = Get-CimAssociatedInstance -Association "MSFT_PartitionToVolume" -InputObject $partition -Namespace $msft_namespace
if ($null -ne $Volume -and "CSVFS" -eq $Volume.FileSystem )
{
$volumes[$Volume] = 1;
}
}
return $volumes
}
Function AddTraceMessage
{
param($message)
$errorActionPreference = 'SilentlyContinue'
$timeStamp = (get-date -format "HH:mm:ss:fff");
$script:traceMsg = $script:traceMsg + "`n[" + $timeStamp + "] " + $message;
}
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 Check-CimError($Exception)
{
$errorActionPreference = 'SilentlyContinue'
$result = $false
if ($null -eq $Exception)
{
return $result
}
$error.Clear()
$type = $Exception.GetType()
if (0 -ne $error.Count)
{
$error.Clear()
return $result
}
if ("Microsoft.PowerShell.Cmdletization.Cim.CimJobException" -eq $type.FullName -and $ObjectNotFoundCode -eq $Exception.HResult)
{
$result = $true
}
return $result
}
Function Get-FaultException($exception,$IsObjectExist)
{
if ($false -eq $IsObjectExist)
{
$IsError = Check-CimError -Exception $exception
if ($true -eq $IsError)
{
$exception = $null
}
}
return $exception
}
Function Load-Module ([string] $ModuleName)
{
if ([string]::IsNullOrEmpty($ModuleName) )
{
return $false
}
$ErrorActionPreference="SilentlyContinue"
$error.Clear()
$retval = $false
$Tmodule = Get-Module -Name $ModuleName
########Check for powershell 1.0
if ($error.Count -ne 0)
{
$Exception = $error[0].Exception
if ($null -ne $Exception)
{
$type = $Exception.GetType()
if ([System.Management.Automation.CommandNotFoundException] -eq $type)
{
$error.Clear()
return $retval
}
}
$error.Clear()
}
if ($null -eq $Tmodule)
{
$Tmodule = Get-Module -Name $ModuleName -ListAvailable
if ($error.Count -ne 0){ return $retval;}
if ($null -eq $Tmodule) {return $retval;}
Import-Module $ModuleName
if ($error.Count -eq 0){ $retval = $true;}
}
else
{
$retval = $true
}
return $retval
}
AddTraceMessage -message "Start on Node: $env:COMPUTERNAME"
$IsStorageModuleReady = Load-Module -ModuleName "Storage"
if ($false -eq $IsStorageModuleReady)
{
if ($error.Count -ne 0)
{
$message = "Cannot initializa Storage module. Error: " + $error[0].ToString()
}
else
{
$message = "Cannot load Storage module."
}
AddTraceMessage -message $message
}
#Load cimcmdlets
$IsCimReady = Load-Module -ModuleName "CimCmdLets"
$ITEM_DATA_TYPE = "Item"
$LIST_DATA_TYPE = "List"
$Fail_DATA_TYPE = "fLst"
Function Add-PropertyBag($fault,$SourceUniqueId,$SourceObjectId,$TargetId,[HashTable]$faultIdTbl)
{
$errorActionPreference = 'Stop'
$faultId = $fault.FaultId;
$alertSeverity = 1;
$alertSevString = "$($fault.PerceivedSeverity)"
if($fault.PerceivedSeverity -eq "2" -or $fault.PerceivedSeverity -eq "Information")
{
$alertSeverity = 0 #Information
}
elseif(($fault.PerceivedSeverity -eq "3") -or ($fault.PerceivedSeverity -eq "4") -or ( "Minor" -eq $fault.PerceivedSeverity) -or ("Degraded/Warning" -eq $fault.PerceivedSeverity))
{
$alertSeverity = 1 #Warning
}
elseif(($fault.PerceivedSeverity -ge "5"))
{
$alertSeverity = 2 #Error
}
elseif(("Major" -eq $fault.PerceivedSeverity) -or ("Critical" -eq $fault.PerceivedSeverity ) -or ("Fatal/NonRecoverable" -eq $fault.PerceivedSeverity))
{
$alertSeverity = 2 #Error
}
$propertyBag = $momAPI.CreatePropertyBag()
$propertyBag.AddValue("FaultId", $faultId);
$propertyBag.AddValue("FaultingObjectDescription", $fault.FaultingObjectDescription);
$propertyBag.AddValue("FaultingObjectLocation", $fault.FaultingObjectLocation);
$propertyBag.AddValue("Reason", $fault.Reason);
$propertyBag.AddValue("RecommendedActions", $fault.RecommendedActions -join "`n");
$propertyBag.AddValue("CompositeAlertId", $faultId + ":" + $SourceObjectId);
$propertyBag.AddValue("SourceUniqueId", $SourceUniqueId);
$propertyBag.AddValue("SourceObjectId", $SourceObjectId);
$propertyBag.AddValue("TargetId", $TargetId);
$propertyBag.AddValue("DataType", $ITEM_DATA_TYPE); #required in condition detection for generate/close alerts
$propertyBag.AddValue("Severity", $alertSeverity);
#Publish property bag data
$propertyBag
if ($false -eq [string]::IsNullOrEmpty($faultId))
{
$faultIdTbl[$faultId] = 1
}
}
Function ProcessFaultsByBag($faults,$SourceUniqueId,$SourceObjectId,$TargetId,[HashTable]$faultIdTbl)
{
$errorActionPreference = 'Stop'
if ($null -eq $faults) {return;}
foreach($fault in $faults)
{
Add-PropertyBag -fault $fault -SourceUniqueId $SourceUniqueId -SourceObjectId $SourceObjectId -TargetId $TargetId -faultIdTbl $faultIdTbl
}
}
function Print-TraceData()
{
$errorActionPreference = "SilentlyContinue"
AddTraceMessage -message "Storage monitoring script $SCRIPT_NAME started."
AddTraceMessage -message "InstanceType = $InstanceType."
AddTraceMessage -message "SourceUniqueId = $SourceUniqueId."
AddTraceMessage -message "TargetId = $TargetId."
AddTraceMessage -message "TargetInstanceObjectID=$TargetInstanceObjectID"
AddTraceMessage -message "SourceObjectId=$SourceObjectId"
$error.Clear()
}
#Param($TargetInstanceObjectID,$InstanceType, $SourceUniqueId, $SourceObjectId, $TargetId,$VirtualDiskId,$DebugMode)
Function Get-VirtualDiskById($UniqueID)
{
$ErrorActionPreference = 'Stop'
$vd = $null
try
{
$vd = Get-VirtualDisk -UniqueID $UniqueID
}
catch
{
$exception = Get-FaultException -exception $_.Exception -IsObjectExist $false
if ($null -ne $exception)
{
Throw $exception
}
}
return $vd
}
Function Get-VolumeById($UniqueID)
{
$ErrorActionPreference = 'Stop'
$IsWmiError = $False;
$Volumes = $null
try
{
$Volumes = Get-Volume -UniqueID $UniqueID
}
catch
{
$exception = Get-FaultException -exception $_.Exception -IsObjectExist $false
if ($null -ne $exception)
{
$IsWmiError = $true
Throw $exception
}
}
finally
{
#Check if virtual disk is offline
#In this case generate exception and don't generate new faults and close old volume faults
if ($null -eq $Volumes -and $false -eq $IsWmiError)
{
$vd = Get-VirtualDiskById -UniqueID $VirtualDiskId
if ($null -ne $vd -and "OK" -ne $vd.OperationalStatus )
{
$ex = New-Object -TypeName "System.NotSupportedException" -ArgumentList ("Virtual Disk is not in operational state.")
Throw $ex
}
}
}
return $volumes
}
Function Get-FauiltsByObjectId([string]$Id,[string]$instanceType,[ref]$storageObjectsCount)
{
$ErrorActionPreference = 'Stop'
$objects = $null
$ex = $null
$result = $null
$IsExist = $false
try
{
if ("SSS" -eq $instanceType)
{
$objects = Get-StorageSubSystem -UniqueID $Id
$IsExist = $true
if ($null -ne $objects)
{
$result = $objects | Debug-StorageSubSystem
}
}
elseif("V" -eq $instanceType)
{
$objects = Get-VolumeById -UniqueID $Id
$IsExist = $true
if ($null -ne $objects)
{
$result = $objects | Debug-Volume
}
}
elseif("FS" -eq $instanceType)
{
$objects = Get-FileShare -UniqueID $Id
$IsExist = $true
if ($null -ne $objects)
{
$result = $objects | Debug-FileShare
}
}
else
{
$ex = New-Object -TypeName "System.NotSupportedException" -ArgumentList ("Type of storage instance is not supported")
Throw $ex
}
}
catch
{
$exception = Get-FaultException -exception $_.Exception -IsObjectExist $IsExist
if ($null -ne $exception)
{
Throw $exception
}
}
if ($null -eq $objects)
{
return $null
}
else
{
$oCount = $objects.Count
if ($null -eq $oCount){$oCount = 1;}
if ($null -ne $storageObjectsCount)
{
$storageObjectsCount.Value = $oCount
}
}
if ($null -ne $result)
{
$result = @($result)
}
return $result
}
Function Get-Faults
{
param($instanceType, $UniqueID,[ref]$storageObjectsCount)
$errorActionPreference = 'Stop'
$error.Clear()
$result = $null
if ([string]::IsNullOrEmpty($UniqueID))
{
Throw [System.ArgumentException] "Get-Faults: Cannot validate argument on parameter 'UniqueId'. The argument is empty."
}
if ([string]::IsNullOrEmpty($UniqueID.Trim()))
{
Throw [System.ArgumentException] "Get-Faults: Cannot validate argument on parameter 'UniqueId'. The argument is empty."
}
$objectsCount = 0
$result = (Get-FauiltsByObjectId -Id $UniqueID -instanceType $instanceType -storageObjectsCount ([ref]$objectsCount))
if ($null -ne $storageObjectsCount){$storageObjectsCount.Value = $objectsCount;}
return $result
}
function Add-ResultFaults([string]$faultIds,$IsError)
{
$errorActionPreference = 'Stop'
$ItemType = $LIST_DATA_TYPE
##########################################################
# If Error occuried donn't return any data to close alert
##########################################################
if ($true -eq $IsError)
{
AddTraceMessage -message "Error occuried during faults proccessing. Don't return faults list to close."
return
}
AddTraceMessage -message "joined id list [$faultIds]"
try
{
$listPropertyBag = $momAPI.CreatePropertyBag()
$listPropertyBag.AddValue("FaultId", $faultIds);
$listPropertyBag.AddValue("SourceUniqueId", $SourceUniqueId);
$listPropertyBag.AddValue("SourceObjectId", $SourceObjectId);
$listPropertyBag.AddValue("TargetId", $TargetId);
$listPropertyBag.AddValue("DataType", $ItemType);
$listPropertyBag
AddTraceMessage -message "Final propertyBag was added. "
}
catch [System.Exception]
{
AddTraceMessage -message "Cannot create final Fault list property Bag. "
AddTraceMessage -message $_.Exception.Message
}
}
function Start-FinalAction($IsError,$IsFaultReturn,$IsAddingDataComplete,$Exception,[string]$faultIds)
{
$errorActionPreference = 'SilentlyContinue'
if ($false -eq $IsFaultReturn)
{
AddTraceMessage -message "Cannot get faults data."
}
else
{
if($false -eq $IsAddingDataComplete)
{
AddTraceMessage -message "Not all faults have been processed successfully"
}
}
Add-ResultFaults -faultIds $faultIds -IsError $IsError
Log-FinalDebugData -FailureEvent $GenericFailureEvent -InformationEvent $GenericInformationEvent -exception $exception -SCRIPT_NAME $SCRIPT_NAME -traceMsg $script:traceMsg -DebugMode $DebugMode
}
Function ProcessData($faults,[ref]$faultIds)
{
$errorActionPreference = "Stop"
$faultIdString = [string]::Empty
if ($null -eq $faults)
{
return
}
$faultIdHash = @{}
ProcessFaultsByBag -faults $faults -SourceUniqueId $SourceUniqueId -SourceObjectId $SourceObjectId -TargetId $TargetId -faultIdTbl $faultIdHash
if (0 -ne $faultIdHash.Count)
{
$faultIdString = [string]::Join(",",@($faultIdHash.Keys))
}
if($faultIds -ne $null)
{
$faultIds.Value = $faultIdString
}
$faultCount = $faults.Count
if ($null -eq $faultCount)
{
$faultCount = 1
}
AddTraceMessage -message "Get Faults: $($faultCount) fault(s) has been proccessed."
}
function Main()
{
$errorActionPreference = "Stop"
$IsError = $false
$IsFaultReturn = $false
$IsAddingDataComplete = $false
$faultIds = [string]::Empty
$storageObjectsCount = 0
Print-TraceData
if ($TargetInstanceObjectID -ne $SourceObjectId)
{
AddTraceMessage -message "Faults were not found for this target : $TargetInstanceObjectID"
Start-FinalAction -IsError $true -IsFaultReturn $IsFaultReturn -IsAddingDataComplete $IsAddingDataComplete -Exception $null -faultIds $faultIds
return
}
if ($false -eq $IsStorageModuleReady)
{
$momAPI.LogScriptEvent($scriptName, $GenericFailureEvent, 1, $script:traceMsg);
Start-FinalAction -IsError $true -IsFaultReturn $IsFaultReturn -IsAddingDataComplete $IsAddingDataComplete -Exception $null -faultIds $faultIds
return
}
try
{
$faults = Get-Faults -instanceType $InstanceType -UniqueID $SourceUniqueId -storageObjectsCount ([ref] $storageObjectsCount)
$IsFaultReturn = $true
if($null -eq $faults)
{
if (0 -eq $storageObjectsCount)
{
AddTraceMessage -message "Storage object with Id:[$SourceUniqueId] was not found"
}
else
{
AddTraceMessage -message "Faults were not found."
}
}
else
{
if (0 -eq $faults.Count)
{
AddTraceMessage -message "faults were not found"
}
ProcessData -faults $faults -faultIds ([ref] $faultIds)
}
$IsAddingDataComplete = $true
}
catch
{
##################################################
# There are the following reason of exception
# 1. From Get-Faults. If and only if:
# 1.1 Bad SourceUniqueId (null or contains only spaces)
# 1.2 Exception during Get-Storage.. cmdlets
# 1.3 Exception during Debug Cmdlets
# 2. Exception in Add-propertyBag (Maybe incomplete fault data)
#
#
##################################################
$IsError = $true
$Exception = $_.Exception
AddTraceMessage -message $Exception.Message
}
finally
{
Start-FinalAction -IsError $IsError -IsFaultReturn $IsFaultReturn -IsAddingDataComplete $IsAddingDataComplete -Exception $Exception -faultIds $faultIds
}
}
Main
</Script> </ScriptBody>
<Parameters>
<Parameter>
<Name>TargetInstanceObjectID</Name>
<Value>$Config/TargetInstanceObjectID$</Value>
</Parameter>
<Parameter>
<Name>InstanceType</Name>
<Value>$Config/InstanceType$</Value>
</Parameter>
<Parameter>
<Name>SourceUniqueId</Name>
<Value>$Config/TargetInstanceUniqueID$</Value>
</Parameter>
<Parameter>
<Name>SourceObjectId</Name>
<Value>$Data/Property[@Name='SourceObjectId']$</Value>
</Parameter>
<Parameter>
<Name>TargetId</Name>
<Value>$Config/TargetId$</Value>
</Parameter>
<Parameter>
<Name>VirtualDiskId</Name>
<Value>$Config/VirtualDiskId$</Value>
</Parameter>
<Parameter>
<Name>bagType</Name>
<Value>$Config/bagType$</Value>
</Parameter>
<Parameter>
<Name>DebugMode</Name>
<Value>$Config/DebugMode$</Value>
</Parameter>
</Parameters>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
<StrictErrorHandling>true</StrictErrorHandling>
</ProbeAction>
<!--<ConditionDetection ID="CD" TypeID="System!System.ExpressionFilter">
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="String">Property[@Name='SourceUniqueId']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value>$Config/TargetInstanceUniqueID$</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</ConditionDetection>-->
</MemberModules>
<Composition>
<!--<Node ID="CD">-->
<Node ID="PA">
<Node ID="WmiEventProviderDS"/>
</Node>
<!--</Node>-->
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.PropertyBagData</OutputType>
</DataSourceModuleType>