Public/Export-SCOMKnowledge.ps1
|
Function Export-SCOMKnowledge { <# .SYNOPSIS This script will get all rule and monitor knowledge article content and output the information to separate files (Rules.html and Monitors.html) in the output folder path specified. .PARAMETER OutFolder The output folder path where output files will be created. Must be a container/directory, not a file. .PARAMETER ManagementPack A collection/array of one or more management pack objects. .PARAMETER MgmtServerFQDN Alias: ManagementServer Fully Qualified Domain Name of the SCOM management server. .PARAMETER NoKnowledgeExclude By default ALL workflows will be included in the output files. Enable this switch to exclude workflows which have no Knowledge Article content. .PARAMETER ExportCSV Export results to CSV files instead of default format (.html) .PARAMETER Topic This will customize the name of the output files. Useful when dumping multiple sets to the same output folder. .PARAMETER ShowResult Will open the Windows file Explorer to show output files. .EXAMPLE (Get-SCOMManagementPack -Name *.AD.*) | Export-SCOMKnowledge -OutFolder 'C:\MyReports' -Topic "AD_" -ShowResult In the example above the variable will be assigned a collection of all management pack objects with ".AD." in the name. That subset/collection of management pack objects will be passed into the script. The script will output workflow details for all Rules and Monitors contained in ALL management packs within that set. The output file names will be: "AD_Rules.html" and "AD_Monitors.html". Finally the script will open Windows File Explorer to the location of the output directory. .Example PS C:\> Export-SCOMKnowledge -OutFolder 'C:\Export' -ManagementPack (Get-SCOMManagementPack -Name "*ad.*") -Filter '201[0-6]' The command above will output all rules/monitors from management packs which contain 'ad.' in the Name and which contain '201x' in the Name or DisplayName of the workflow where 'x' represents any single digit 0-6 . .EXAMPLE PS C:\> Export-SCOMKnowledge -OutFolder "C:\Temp" -ManagementPack (Get-SCOMManagementPack -Name *SQL*) -Topic "SQL_Packs_" The command above will output workflow details for all Rules and Monitors contained in ALL management packs with "SQL" in the management pack Name. The output file names will be: "SQL_Packs_Rules.html" and "SQL_Packs_Monitors.html" .EXAMPLE PS C:\> Export-SCOMKnowledge -OutFolder "C:\MyReports" -ManagementServer "ms01.contoso.com" -NoKnowledgeExclude In the example above, the command will connect to management server: "ms01.contoso.com", will output workflow details for all Rules and Monitors (only if they contain a Knowledge Article) to two separate files in the specified folder. The output file names will be: "Rules.html" and "Monitors.html" .Example PS C:\> Export-SCOMKnowledge -OutFolder 'C:\Export' -ManagementPack (Get-SCOMManagementPack -Name "*ad.*") -Filter '(?=200[0-8])((?!Monitoring).)*$' The command above will output all rules/monitors from management packs which contain 'ad' in the Name and which contain '200x' in the Name or DisplayName of the workflow where 'x' is numbers 1-8 but excluding workflows that contain 'monitoring'. .Example #Export SCOM Knowledge for rules/monitors Get-SCOMManagementGroupConnection | Remove-SCOMManagementGroupConnection -Verbose New-SCOMManagementGroupConnection -ComputerName YOUR_SERVERNAME $SQLMPs = Get-SCOMManagementPack -Name *sql* $Outfolder = 'D:\SCOMReports' # Workflows to separate files ForEach ($MP in $SQLMPs){ $rules = $MP.GetRules().Count $mons = $MP.GetMonitors().Count If (($rules + $mons) -gt 0){ Export-SCOMKnowledge -OutFolder $Outfolder -ManagementPack $MP -Topic "$($MP.Name)_" } Else{ Write-Host "No monitor/rule workflows found: " -NoNewline; Write-Host "$($MP.DisplayName)" -f Yellow } } #All MPs combined Export-SCOMKnowledge -OutFolder $Outfolder -ManagementPack $SQLMPs -Topic "ALL_SQL_" .LINK https://monitoringguys.com/ .NOTES Author: Tyson Paul Blog: https://monitoringguys.com/ History: 2022.06.20: Used arraylist to improve speed when gathering rules/mons. Leveraged new Convert-MAML2HTML function for article conversion. 2017/12/05: Added Topic parameter to customize output file names. Added ShowResult switch. 2017/10/16: Added support for regex filtering on DisplayName or Name of monitors/rules. 2016/05/03: Added option to export to CSV. Although embedded tables in the KnowledgeArticle don't convert very well. 2016/04/26: Improved formatting of output files. Now includes embedded parameter tables and restored article href links. 2016/04/26: Fixed script to accept ManagementPack pipeline input #> [CmdletBinding(DefaultParameterSetName='Parameter Set 1', SupportsShouldProcess=$false, SupportsPaging = $true, PositionalBinding=$false)] Param( #1 [Parameter(Mandatory=$true, ValueFromPipeline=$false, Position=0, ParameterSetName='Parameter Set 1')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [string]$OutFolder, #2 [Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ValueFromRemainingArguments=$false, Position=1, ParameterSetName='Parameter Set 1')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [System.Object[]]$ManagementPack, #3 [Parameter(Mandatory=$false, ValueFromPipeline=$false, Position=2, ParameterSetName='Parameter Set 1')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [Alias("ManagementServer")] [string]$MgmtServerFQDN, #4 [Parameter(Mandatory=$false, Position=3, ParameterSetName='Parameter Set 1')] [Switch]$NoKnowledgeExclude, #5 [Parameter(Mandatory=$false, ValueFromPipeline=$false, Position=4, ParameterSetName='Parameter Set 1')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [string]$OpsDBServer, #6 [Parameter(Mandatory=$false, ValueFromPipeline=$false, Position=5, ParameterSetName='Parameter Set 1')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [string]$OpsDBName, #7 [Parameter(Mandatory=$false, ValueFromPipeline=$false, Position=6, ParameterSetName='Parameter Set 1')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [string]$Topic, #8 [Parameter(Mandatory=$false, Position=7, ParameterSetName='Parameter Set 1')] [Alias("WorkflowFilter")] [string[]]$Filter, #9 [Parameter(Mandatory=$false, Position=8, ParameterSetName='Parameter Set 1')] [switch]$ExportCSV, #10 [Parameter(Mandatory=$false, Position=9, ParameterSetName='Parameter Set 1')] [switch]$ShowResult=$false ) #### UNCOMMENT FOR TESTING #### #$OutFolder = "c:\Test" #region Functions 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) $articleContent = ($MamlText | ForEach-Object { Convert-MAMLToHtml -XML $_ }) } If ($null -ne $article.HtmlContent) { $HtmlText = $article.HtmlContent $articleContent = CleanHTML($HtmlText) } } If ($null -eq $articleContent) { $articleContent = "No resolutions were found for this alert." } Return $articleContent } #------------------------------------------------------------------------------------ Function ProcessWorkflows { Param( $Workflows, [string]$WFType ) $thisWFType = $WFType $myWFCollectionObj = @() [int]$row=1 ForEach ($thisWF in $Workflows) { Write-Progress -Activity "Processing $WFType" -status "Getting Alert [$($row)]: $($thisWF.DisplayName) " -percentComplete ($row / $($Workflows.count) * 100) #$ErrorActionPreference = 'SilentlyContinue' $article = $NULL Try { $article = $thisWF.GetKnowledgeArticle($cultureInfo) } Catch { #Empty catch is fine here } If (-NOT $article){ $error.Remove($Error[0]) $articlecontent = "None" If ($NoKnowledgeExclude){ Continue; } } Else{ $articleContent = ProcessArticle $article } If ($ExportCSV) { $WFName = $($thisWF.Name) $WFDisplayName = $($thisWF.DisplayName) } Else { $WFName = '<name>' + $($thisWF.Name) + '</name>' $WFDisplayName = '<displayname>' + $($thisWF.DisplayName) + '</displayname>' } $WFDescription = $thisWF.Description If ($WFDescription.Length -lt 1) {$WFDescription = "None"} #region Get_alert_name If ($WFType -like "Rule") { $thisWFType = "$($WFType): " + "$($thisWF.WriteActionCollection.Name)" # Proceed only if rule is an "alert" rule. If ($thisWF.WriteActionCollection.Name -Like "GenerateAlert"){ $AlertMessageID = $($thisWF.WriteActionCollection.Configuration).Split('"',3)[1] $Query = @" Select [LTValue] FROM [OperationsManager].[dbo].[LocalizedText] WHERE ElementName like '$($AlertMessageID)' AND LTStringType = '1' "@ $AlertDisplayName = priv_Invoke-CLSqlCmd -Query $Query -Server $OpsDBServer -Database $OpsDBName If ($ExportCSV) { $AlertName = $AlertDisplayName } Else { $AlertName = '<alertname>' + $AlertDisplayName + '</alertname>' } } Else { If ($ExportCSV) { $AlertName = 'N/A' } Else { $AlertName = '<noalertname>N/A</noalertname>' } } } Else { # Workflow is not a rule, therefore it is a monitor. $Query = @" Select LocalizedText.LTValue From [OperationsManager].[dbo].[LocalizedText] INNER JOIN [OperationsManager].[dbo].[Monitor] on LocalizedText.LTStringId=Monitor.AlertMessage Where Monitor.MonitorID like '$($thisWF.ID)' AND LocalizedText.LTStringType = '1' "@ $AlertDisplayName = priv_Invoke-CLSqlCmd -Query $Query -Server $OpsDBServer -Database $OpsDBName # Not all monitors generate an alert. If ($AlertDisplayName -like "EMPTYRESULT") { If ($ExportCSV) { $AlertName = 'N/A' } Else { $AlertName = '<noalertname>N/A</noalertname>' } } Else { If ($ExportCSV) { $AlertName = $AlertDisplayName } Else { $AlertName = '<alertname>' + $AlertDisplayName + '</alertname>' } } } #endregion Get_alert_name $WFID = $thisWF.ID $WFMgmtPackID = $thisWF.GetManagementPack().Name # Build the custom object to represent the workflow, add properties/values. $myWFObj = New-Object -TypeName System.Management.Automation.PSObject $myWFObj | Add-Member -MemberType NoteProperty -Name "Row" -Value $Row $myWFObj | Add-Member -MemberType NoteProperty -Name "DisplayName" -Value $WFDisplayName $myWFObj | Add-Member -MemberType NoteProperty -Name "AlertName" -Value $AlertName $myWFObj | Add-Member -MemberType NoteProperty -Name "KnowledgeArticle" -Value $articleContent $myWFObj | Add-Member -MemberType NoteProperty -Name "Description" -Value $WFDescription $myWFObj | Add-Member -MemberType NoteProperty -Name "ManagementPackID" -Value $WFMgmtPackID $myWFObj | Add-Member -MemberType NoteProperty -Name "Name" -Value $WFName $myWFObj | Add-Member -MemberType NoteProperty -Name "WorkflowType" -Value $thisWFType $myWFObj | Add-Member -MemberType NoteProperty -Name "ID" -Value $WFID $myWFCollectionObj += $myWFObj $Row++ } Return $myWFCollectionObj } #------------------------------------------------------------------------------------ Function fnMamlToHTML{ param ( $MAMLText ) $HTMLText = ""; $HTMLText = $MAMLText -replace ('xmlns:maml="http://schemas.microsoft.com/maml/2004/10"'); $HTMLText = $HTMLText -replace ("<maml:section>"); $HTMLText = $HTMLText -replace ("<maml:section >"); $HTMLText = $HTMLText -replace ("</maml:section>"); $HTMLText = $HTMLText -replace ("<section >"); #ui = underline. Not going to bother with this html conversion $HTMLText = $HTMLText -replace ("<maml:ui>", ""); $HTMLText = $HTMLText -replace ("</maml:ui>", ""); #Only convert the maml tables if not exporting to CSV IF ($ExportCSV) { $HTMLText = $HTMLText -replace ("<maml:para>", " "); $HTMLText = $HTMLText -replace ("<maml:para />", " "); $HTMLText = $HTMLText -replace ("</maml:para>", " "); $HTMLText = $HTMLText -replace ("<maml:title>", ""); $HTMLText = $HTMLText -replace ("</maml:title>", ""); $HTMLText = $HTMLText -replace ("<maml:list>", ""); $HTMLText = $HTMLText -replace ("</maml:list>", ""); $HTMLText = $HTMLText -replace ("<maml:listitem>", ""); $HTMLText = $HTMLText -replace ("</maml:listitem>", ""); $HTMLText = $HTMLText -replace ("<maml:table>", ""); $HTMLText = $HTMLText -replace ("</maml:table>", ""); $HTMLText = $HTMLText -replace ("<maml:row>", ""); $HTMLText = $HTMLText -replace ("</maml:row>", ""); $HTMLText = $HTMLText -replace ("<maml:entry>", ""); $HTMLText = $HTMLText -replace ("</maml:entry>", ""); $HTMLText = $HTMLText -replace ('<tr><td><p>Name</p></td><td><p>Description</p></td><td><p>Default Value</p></td></tr>', 'Name Description DefaultValue'); } Else { $HTMLText = $HTMLText -replace ("maml:para", "p"); $HTMLText = $HTMLText -replace ("<maml:table>", "<table>"); $HTMLText = $HTMLText -replace ("</maml:table>", "</table>"); $HTMLText = $HTMLText -replace ("<maml:row>", "<tr>"); $HTMLText = $HTMLText -replace ("</maml:row>", "</tr>"); $HTMLText = $HTMLText -replace ("<maml:entry>", "<td>"); $HTMLText = $HTMLText -replace ("</maml:entry>", "</td>"); $HTMLText = $HTMLText -replace ("<maml:title>", "<h3>"); $HTMLText = $HTMLText -replace ("</maml:title>", "</h3>"); $HTMLText = $HTMLText -replace ("<maml:list>", "<ul>"); $HTMLText = $HTMLText -replace ("</maml:list>", "</ul>"); $HTMLText = $HTMLText -replace ("<maml:listitem>", "<li>"); $HTMLText = $HTMLText -replace ("</maml:listitem>", "</li>"); $HTMLText = $HTMLText -replace ('<tr><td><p>Name</p></td><td><p>Description</p></td><td><p>Default Value</p></td></tr>', '<th>Name</th><th>Description</th><th>Default Value</th>'); } # Replace all maml links with html href formatted links while ($HTMLText -like "*<maml:navigationLink>*"){ If ($HtmlText -like "*uri condition*" ) { $HTMLText = Fix-HREF -mystring $HTMLText -irregular } Else { $HTMLText = Fix-HREF -mystring $HTMLText } } Return $HTMLText; } #------------------------------------------------------------------------------------ Function CleanHTML{ param ( $HTMLText ) $TrimedText = ""; $TrimedText = $HTMLText -replace ("<", "<") $TrimedText = $TrimedText -replace (">", ">") $TrimedText = $TrimedText -replace (""", '"') $TrimedText = $TrimedText -replace ("&", '&') $TrimedText; } #------------------------------------------------------------------------------------ #Remove maml link formatting, replace with HTML Function Fix-HREF { Param( [string]$mystring, [switch]$irregular ) If ($irregular){ $href_link_tag_begin = '<maml:uri condition' } Else { $href_link_tag_begin = '<maml:uri href="' $href_name_tag_begin = '<maml:navigationLink><maml:linkText>' $href_name_tag_end = '</maml:linkText>' $href_link_tag_end = '" /></maml:navigationLink>' $href_name_length = ($mystring.IndexOf($href_name_tag_end)) - ( $mystring.IndexOf($href_name_tag_begin) + $href_name_tag_begin.Length) $href_name = $mystring.Substring( ($mystring.IndexOf($href_name_tag_begin) + $href_name_tag_begin.Length ), $href_name_length) $href_link_length = ($mystring.IndexOf($href_link_tag_end)) - ( $mystring.IndexOf($href_link_tag_begin) + $href_link_tag_begin.Length -1) $href_link = $mystring.Substring( ($mystring.IndexOf($href_link_tag_begin) + $href_link_tag_begin.Length ), $href_link_length -1) } $Chunk_Name = $mystring.Substring( $mystring.IndexOf($href_name_tag_begin), (($mystring.IndexOf($href_name_tag_end) + $href_name_tag_end.Length - 1) - $mystring.IndexOf($href_name_tag_begin) +1 ) ) $Chunk_HREF = $mystring.Substring( $mystring.IndexOf($href_link_tag_begin), (($mystring.IndexOf($href_link_tag_end) + $href_link_tag_end.Length - 1) - $mystring.IndexOf($href_link_tag_begin) +1 ) ) If ($irregular){ $newstring = $mystring.Replace(("$Chunk_Name" + "$Chunk_HREF"), '' ) } Else { #Example: <a href="http://www.bing.com">here</a> to go to Bing. $newstring = $mystring.Replace(("$Chunk_Name" + "$Chunk_HREF"), ('<a href="' + $href_link + '">' + "$href_name" + '</a>') ) } Return $newstring } #------------------------------------------------------------------------------------ Function priv_Invoke-CLSqlCmd { param( [string]$Server, [string]$Database, [string]$Query, [int]$QueryTimeout = 30, #The time in seconds to wait for the command to execute. The default is 30 seconds. [int]$ConnectionTimeout = 15 #The time (in seconds) to wait for a connection to open. The default value is 15 seconds. ) BEGIN { } PROCESS { try { $sqlConnection = New-Object System.Data.SqlClient.SqlConnection $sqlConnection.ConnectionString = "Server=$Server;Database=$Database;Trusted_Connection=True;Connection Timeout=$ConnectionTimeout;" $sqlConnection.Open() try { $sqlCmd = New-Object System.Data.SqlClient.SqlCommand $sqlCmd.CommandText = $Query $sqlCmd.CommandTimeout = $QueryTimeout $sqlCmd.Connection = $SqlConnection try { $Value = @() $sqlReader = $sqlCmd.ExecuteReader() #The default position of the SqlDataReader is before the first record. #Therefore, you must call Read to begin accessing any data. #Return Value: true if there are more rows; otherwise false. If ($sqlReader.Read()) { # $NUL #function returns true. pipe to nowhere. $Value = ($sqlReader.GetValue(0), $sqlReader.GetName(0)) If ( ($Value[1].ToString().Length -eq 0) -and ($sqlReader.Fieldcount -eq 2) ) { #Write-Host "NoName!" -foreground Yellow -background Red try{ $ResultName = $sqlReader.GetValue(1) } finally { } If ($ResultName) { $Value[1]=$ResultName } Else{ $Value[1]='Name' } } #Write-Host "Value2: $Value2" } Else{ $Value = ("EMPTYRESULT",'Result') } } finally { $sqlReader.Close() } } finally { $sqlCmd.Dispose() } } finally { $sqlConnection.Close() } } END { Return $Value[0] } } #endregion priv_Invoke-CLSqlCmd #------------------------------------------------------------------------------------ ##################################################################################### $ThisScript = $MyInvocation.MyCommand.Path [System.Collections.ArrayList]$Rules=@() [System.Collections.ArrayList]$Monitors=@() $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") # If Topic is provided, make sure it contains an underscore. If (($Topic.Length -ge 2) -and (($Topic.IndexOf('_')+1) -ne $Topic.Length) ) { $Topic = "$Topic"+"_" } #Get OpsDB Server name if not provided If (!($OpsDBServer)){ $OpsDBServer = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft Operations Manager\3.0\Setup" -Name "DatabaseServerName").DatabaseServerName } #Get OpsDB name if not provided If (!($OpsDBName)){ $OpsDBName = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft Operations Manager\3.0\Setup" -Name "DatabaseName").DatabaseName } # 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 } } $Error.Clear() #Connect to Localhost Note: perhaps this can be done differently/cleaner/faster if connecting to self? Write-Host "Connecting to: $MgmtServerFQDN ..." -ForegroundColor Gray -BackgroundColor Black New-SCManagementGroupConnection -Computer $MgmtServerFQDN # | Out-Null If ($Error) { Write-Host "Failed to connect to: $MgmtServerFQDN ! Exiting. " -ForegroundColor Red -BackgroundColor Yellow Exit } Else { Write-Host "Connected to: $MgmtServerFQDN " -ForegroundColor Magenta -BackgroundColor Black } #Set Culture Info $cultureInfo = [System.Globalization.CultureInfo]'en-US' $cssHead = @" <style> displayname { color: blue; font: 16px Arial, sans-serif; } alertname { color: red; font: 16px Arial, sans-serif; } noalertname { color: grey; font: 16px Arial, sans-serif; } name { font: 10px Arial, sans-serif; } body { font: normal 14px Verdana, Arial, sans-serif; } table, th, td { border-collapse: collapse; border: 1px solid black; } th, td { padding: 10px; text-align: left; } tr:hover {background-color: #ccffcc} th { background-color: #4CAF50; color: white; } </style> "@ # Make sure output folder exists If (-not (Test-Path -Path $OutFolder -PathType Container )) { New-Item -Path $OutFolder -ItemType Directory -Force -ErrorAction Stop } # If output files already exist, remove them "Rules.html","Monitors.html" | ForEach-Object { If (Test-Path -PathType Leaf (Join-Path $OutFolder $_) ) { Remove-Item -Path (Join-Path $OutFolder $_) -Force } } } #endregion Begin #region Process { # If a set of MPs is specified, only process workflows contained in the MPs. If ($ManagementPack){ $ManagementPack | Select-Object DisplayName,Name,ID,Version | Format-Table -AutoSize # If filter keyword(s) exist, then filter the results according to the regex patterns submitted in the parameter value. If ($Filter) { Foreach ($ThisRegex in $Filter) { Write-Host "Getting all filtered Rules..." -ForegroundColor Yellow ( (Get-SCOMRule -ManagementPack $ManagementPack | Where-Object {( $_.Name -match "$ThisRegex") -OR ( $_.DisplayName -match "$ThisRegex")} ) | ForEach-Object {$NULL = $Rules.Add($_) }) Write-Host "Getting all filtered Monitors..." -ForegroundColor Yellow ( (Get-SCOMMonitor -ManagementPack $ManagementPack | Where-Object {( $_.Name -match "$ThisRegex") -OR ( $_.DisplayName -match "$ThisRegex")} ) | ForEach-Object {$NULL = $Monitors.Add($_) }) } } # If no filter(s) exist, then return all rules/mons from the designated MP. Else { Write-Host "Getting ALL Rules..." -ForegroundColor Yellow ( (Get-SCOMRule -ManagementPack $ManagementPack ) | ForEach-Object {$NULL = $Rules.Add($_) }) Write-Host "Getting ALL Monitors..." -ForegroundColor Yellow ( (Get-SCOMMonitor -ManagementPack $ManagementPack ) | ForEach-Object {$NULL = $Monitors.Add($_) }) } } # Else, get ALL workflows in ALL MPs Else { # If filter(s) exist, then filter the results according to the regex patterns submitted in the parameter value. If ($Filter) { Foreach ($ThisRegex in $Filter) { Write-Host "Getting all filtered Rules..." -ForegroundColor Yellow ( (Get-SCOMRule | Where-Object {( $_.Name -match "$ThisRegex") -OR ( $_.DisplayName -match "$ThisRegex")}) | ForEach-Object {$NULL = $Rules.Add($_) }) Write-Host "Getting all filtered Monitors..." -ForegroundColor Yellow ( (Get-SCOMMonitor | Where-Object {( $_.Name -match "$ThisRegex") -OR ( $_.DisplayName -match "$ThisRegex")} ) | ForEach-Object {$NULL = $Monitors.Add($_) }) } } Else{ Write-Host "Getting ALL Rules..." -ForegroundColor Yellow ( (Get-SCOMRule) | ForEach-Object {$NULL = $Rules.Add($_) }) Write-Host "Getting ALL Monitors..." -ForegroundColor Yellow ( (Get-SCOMMonitor) | ForEach-Object {$NULL = $Monitors.Add($_) }) } } } #endregion #region End { Write-Host "`nTotal Rules Found: $($Rules.Count)" -BackgroundColor Black -ForegroundColor Green $myRulesObj = ProcessWorkflows -Workflows $Rules -WFType "Rule" If (($ExportCSV)) { $myRulesObjTemp = $myRulesObj | ConvertTo-Csv $myRulesObj = CleanHTML $myRulesObjTemp | ConvertFrom-CSV Write-Host "Exporting rules to CSV: "$(Join-Path $OutFolder ($Topic +"Rules.csv")) -F Cyan #Export to CSV $myRulesObj | Export-Csv -Path $(Join-Path $OutFolder ($Topic +"Rules.csv")) -NoTypeInformation -Encoding UTF8 } Else { $RulesTempContent = $myRulesObj | ConvertTo-HTML -Title "SCOM Rules" -Head $cssHead $RulesTempContent = CleanHTML $RulesTempContent $RulesTempContent = $RulesTempContent -Replace '<table>', '<table border="1" cellpadding="20">' $RulesTempContent | Set-Content (Join-Path $OutFolder ($Topic +"Rules.html")) -Encoding UTF8 } Write-Host "Total Monitors Found: $($Monitors.Count)" -BackgroundColor Black -ForegroundColor Green $myMonitorObj = ProcessWorkflows -Workflows $Monitors -WFType "Monitor" If (($ExportCSV)) { $myMonitorObjTemp = $myMonitorObj | ConvertTo-CSV $myMonitorObj = CleanHTML $myMonitorObjTemp | ConvertFrom-CSV Write-Host "Exporting monitors to CSV: "$(Join-Path $OutFolder ($Topic + "Monitors.csv")) -F Cyan #Export to CSV $myMonitorObj | Export-Csv -Path $(Join-Path $OutFolder ($Topic + "Monitors.csv")) -NoTypeInformation -Encoding UTF8 } Else { $MonitorTempContent = $myMonitorObj | ConvertTo-HTML -Title "SCOM Monitors" -Head $cssHead $MonitorTempContent = CleanHTML $MonitorTempContent $MonitorTempContent = $MonitorTempContent -Replace '<table>', '<table border="1" cellpadding="20">' $MonitorTempContent | Set-Content (Join-Path $OutFolder ($Topic + "Monitors.html")) -Encoding UTF8 } Write-host "Output folder: $OutFolder" -BackgroundColor Black -ForegroundColor Yellow If ($ShowResult) { Explorer.exe $OutFolder } } #endregion } |