Public/Get-SCOMAlertKnowledge.ps1
|
Function Get-SCOMAlertKnowledge { <# .SYNOPSIS This function will get workflow details for one or more alerts, including the Knowledge Article content (neatly formatted in HTML). .DESCRIPTION Accepts one parameter, the alert object array of one or more SCOM alert objects: Microsoft.EnterpriseManagement.Monitoring.MonitoringAlert[]. This function can be useful with an automation/ticketing solution. .PARAMETER Alert The alert object(s) to be queried for the workflow details including the Knowledge article (if one exists). .PARAMETER MgmtServerFQDN Fully Qualified Domain Name of the SCOM management server. Alias: ManagementServer .PARAMETER OutputArticleOnly Will output only the Knowledge Article(s) content (neatly formatted in HTML). This may abe useful for situations where a service/ticketing connector is used to get alert properties. .EXAMPLE Get-SCOMAlert | Select-Object -First 1 | Get-SCOMAlertKnowledge Will display alert info (including Knowledge Article in HTML format) for the first alert object returned. .EXAMPLE PS C:\> Get-SCOMAlertKnowledge -Alert (Get-SCOMAlert | Select-Object -First 3) -OutputArticleOnly Will output only the HTML Knowledge Articles for the first 3 alert objects returned. .EXAMPLE PS C:\> Get-SCOMAlertKnowledge -Alert (Get-SCOMAlert -Name *sql*) Will output alert info (including Knowledge Article in HTML format) for any alerts with "sql" in the alert name. .NOTES Author: Tyson Paul Date: 2016/3/31 Blog: https://monitoringguys.com/ #> [CmdletBinding(DefaultParameterSetName='Parameter Set 1', SupportsShouldProcess=$true, SupportsPaging = $true, PositionalBinding=$true)] Param( [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$false, ValueFromRemainingArguments=$false, Position=0, ParameterSetName='Parameter Set 1')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [Microsoft.EnterpriseManagement.Monitoring.MonitoringAlert[]]$Alert, [Parameter(Mandatory=$false, ValueFromPipeline=$false, ValueFromPipelineByPropertyName=$false, ValueFromRemainingArguments=$false, Position=1, ParameterSetName='Parameter Set 1')] [Alias("ManagementServer")] [string]$MgmtServerFQDN = "", [Parameter(Mandatory=$false, ValueFromPipeline=$false, ValueFromPipelineByPropertyName=$false, ValueFromRemainingArguments=$false, Position=2, ParameterSetName='Parameter Set 1')] [Switch]$OutputArticleOnly = $false ) Begin { #------------------------------------------------------------------------------------ Function ProcessArticle { Param( $article ) If ($article -ne "None") #some rules don't have any knowledge articles { #Retrieve and format article content $MamlText = $null $HtmlText = $null If ($null -ne $article.MamlContent) { $MamlText = $article.MamlContent $articleContent = fnMamlToHtml($MamlText) } If ($null -ne $article.HtmlContent) { $HtmlText = $article.HtmlContent $articleContent = fnTrimHTML($HtmlText) } } If ($null -eq $articleContent) { $articleContent = "No resolutions were found for this alert." } Return $articleContent } #------------------------------------------------------------------------------------ Function ProcessWorkflow { Param( $Workflows, [string]$WFType ) $myWFCollectionObj = @() ForEach ($thisWF in $Workflows) { $ErrorActionPreference = 'SilentlyContinue' $article = $thisWF.GetKnowledgeArticle($cultureInfo) If ($? -eq $false){ $error.Remove($Error[0]) $article = "None" } Else{ $articleContent = ProcessArticle $article } $WFName = $thisWF.Name $WFDisplayName = $thisWF.DisplayName $WFDescription = $thisWF.Description $WFID = $thisWF.ID If ($WFDescription.Length -lt 1) {$WFDescription = "None"} #Note: Only a small subset of alert properties are gathered here. Add additional Note Properties as needed using the format below. $myWFObj = New-Object -TypeName System.Management.Automation.PSObject $myWFObj | Add-Member -MemberType NoteProperty -Name "WorkflowType" -Value $WFType $myWFObj | Add-Member -MemberType NoteProperty -Name "Name" -Value $WFName $myWFObj | Add-Member -MemberType NoteProperty -Name "DisplayName" -Value $WFDisplayName $myWFObj | Add-Member -MemberType NoteProperty -Name "Description" -Value $WFDescription $myWFObj | Add-Member -MemberType NoteProperty -Name "ID" -Value $WFID $myWFObj | Add-Member -MemberType NoteProperty -Name "KnowledgeArticle" -Value $articleContent $myWFCollectionObj += $myWFObj } Return $myWFCollectionObj } #------------------------------------------------------------------------------------ Function fnMamlToHTML{ param ( $MAMLText ) $HTMLText = ""; $HTMLText = $MAMLText -replace ('xmlns:maml="http://schemas.microsoft.com/maml/2004/10"'); $HTMLText = $HTMLText -replace ("maml:para", "p"); $HTMLText = $HTMLText -replace ("maml:"); $HTMLText = $HTMLText -replace ("</section>"); $HTMLText = $HTMLText -replace ("<section>"); $HTMLText = $HTMLText -replace ("<section >"); $HTMLText = $HTMLText -replace ("<title>", "<h3>"); $HTMLText = $HTMLText -replace ("</title>", "</h3>"); $HTMLText = $HTMLText -replace ("<listitem>", "<li>"); $HTMLText = $HTMLText -replace ("</listitem>", "</li>"); $HTMLText; } #------------------------------------------------------------------------------------ Function fnTrimHTML($HTMLText){ $TrimedText = ""; $TrimedText = $HTMLText -replace ("<", "<") $TrimedText = $TrimedText -replace (">", ">") <# $TrimedText = $TrimedText -replace ("<html>") $TrimedText = $TrimedText -replace ("<HTML>") $TrimedText = $TrimedText -replace ("</html>") $TrimedText = $TrimedText -replace ("</HTML>") $TrimedText = $TrimedText -replace ("<body>") $TrimedText = $TrimedText -replace ("<BODY>") $TrimedText = $TrimedText -replace ("</body>") $TrimedText = $TrimedText -replace ("</BODY>") $TrimedText = $TrimedText -replace ("<h1>", "<h3>") $TrimedText = $TrimedText -replace ("</h1>", "</h3>") $TrimedText = $TrimedText -replace ("<h2>", "<h3>") $TrimedText = $TrimedText -replace ("</h2>", "</h3>") $TrimedText = $TrimedText -replace ("<H1>", "<h3>") $TrimedText = $TrimedText -replace ("</H1>", "</h3>") $TrimedText = $TrimedText -replace ("<H2>", "<h3>") $TrimedText = $TrimedText -replace ("</H2>", "</h3>") #> $TrimedText; } #------------------------------------------------------------------------------------ ########################################################################################### $ThisScript = $MyInvocation.MyCommand.Path $InstallDirectory = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft Operations Manager\3.0\Setup" -Name "InstallDirectory").InstallDirectory $PoshModulePath = Join-Path (Split-Path $InstallDirectory) PowerShell $env:PSModulePath += (";" + "$PoshModulePath") # Add 2012 Functionality/cmdlets . Import-SCOMPowerShellModule If ($Error) { $modulepaths=$env:PSModulePath.split(';') $Error.Clear() } # If no mgmt server name has been set, assume that local host is the mgmt server. It's worth a shot. If ($MgmtServerFQDN -eq "") { #Get FQDN of local host executing the script (could be any mgmt server when using SCOM2012 Resource Pools) $objIPProperties = [System.Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties() If ($null -eq $objIPProperties.DomainName) { $MgmtServerFQDN = $objIPProperties.HostName } Else { $MgmtServerFQDN = $objIPProperties.HostName + "." +$objIPProperties.DomainName } } #Connect to Localhost Note: perhaps this can be done differently/cleaner/faster if connecting to self? New-SCManagementGroupConnection -Computer $MgmtServerFQDN | Out-Null # If ($Error) { LogIt -EventID 9995 -Type $warn -Message "Log any Errors..." ; $Error.Clear() } #Set Culture Info $cultureInfo = [System.Globalization.CultureInfo]'en-US' $objWFCollection = @() } Process{ #Depending on how the alert object(s) are passed in, the ForEach may be needed. (parameter vs. piped) ForEach ($objAlert in $Alert) { $workflowID = $objAlert.MonitoringRuleId $bIsMonitorAlert = $objAlert.IsMonitorAlert If ($bIsMonitorAlert -eq $false) { $WFType = "Rule" $workflow = Get-SCOMRule -Id $workflowID } ElseIf ($bIsMonitorAlert -eq $true) { $WFType = "Monitor" $workflow = Get-SCOMMonitor -Id $workflowID } # The funciton being called is designed to accept one or more workflows. # It will return one or more custom objects with workfow details, including (most importantly) the KnowlegeArticle. $objWFCollection += ProcessWorkflow -Workflows $Workflow -WFType $WFType } } #End Process End{ If ($OutputArticleOnly){ Return $objWFCollection.KnowledgeArticle } Else{ Return $objWFCollection } } } |