jimmy20
jimmy20

Reputation: 43

Filtering words from paragraph powershell

Am using psbbix module for some operations to manage zabbix from powershell.

This following command gives the whole body which I configured in trigger.

Get-ZabbixAlert | select @{n="test";e={$_.message}}

Output:

"test"
"<b>Problem started</b> at 03:03:09 on 2021.05.28<br><b>Problem name:</b> High memory utilization (>90% for 5m)<br><b>Host:</b> Server-01<br><b>Severity:</b> Average<br><b>Operational data:</b> 90.98 %<br><b>Original problem ID:</b> 21357998<br> <br> <b> IP Address: </b> 10.0.0.99 "
"<b>Problem started</b> at 03:05:07 on 2021.05.28<br><b>Problem name:</b> Load average is too high (per CPU load over 1.5 for 5m)<br><b>Host:</b> Server-02<br><b>Severity:</b> High<br><b>Operational data:</b> Load averages(1m 5m 15m): (15.26 11.73 10.47), # of CPUs: 4<br><b>Original problem ID:</b> 21358922<br> <br> <b> IP Address: </b> 10.0.0.121 "

Here I need to filter the following lines:

Host: Server-01
Severity: Average
Host: Server-02
Severity: High

How to do this? any help?

#Edit 2

enter image description here

Upvotes: 0

Views: 157

Answers (1)

Theo
Theo

Reputation: 61218

It looks like zabbix returns its message in HTML format.

I'm using your example as Here-String, but you should get it using

# get the message in a variable
$zabbixMessage = Get-ZabbixAlert | Select-Object -ExpandProperty message
$zabbixMessage = @'
"<b>Problem started</b> at 03:03:09 on 2021.05.28<br><b>Problem name:</b> High memory utilization (>90% for 5m)<br><b>Host:</b> Server-01<br><b>Severity:</b> Average<br><b>Operational data:</b> 90.98 %<br><b>Original problem ID:</b> 21357998<br> <br> <b> IP Address: </b> 10.0.0.99 "
"<b>Problem started</b> at 03:05:07 on 2021.05.28<br><b>Problem name:</b> Load average is too high (per CPU load over 1.5 for 5m)<br><b>Host:</b> Server-02<br><b>Severity:</b> High<br><b>Operational data:</b> Load averages(1m 5m 15m): (15.26 11.73 10.47), # of CPUs: 4<br><b>Original problem ID:</b> 21358922<br> <br> <b> IP Address: </b> 10.0.0.121 "
'@

$regex = [regex] 'Host:</b>\s*(?<host>[^<]+)<br><b>Severity:</b>\s*(?<severity>[^<]+)<br>'
$match = $regex.Match($zabbixMessage)
while ($match.Success) {
    "Host: $($match.Groups['host'].Value)"
    "Severity: $($match.Groups['severity'].Value)"
    $match = $match.NextMatch()
} 

Output:

Host: Server-01
Severity: Average
Host: Server-02
Severity: High

Or create objects of the values so you can display in table format and/or save as Csv file:

$regex = [regex] 'Host:</b>\s*(?<host>[^<]+)<br><b>Severity:</b>\s*(?<severity>[^<]+)<br>'
$match = $regex.Match($zabbixMessage)
$result = while ($match.Success) {
    [PsCustomObject]@{
        Host     = $match.Groups['host'].Value
        Severity = $match.Groups['severity'].Value
    }
    $match = $match.NextMatch()
} 

# display as table on screen
$result | Format-Table -AutoSize

# export to a CSV file
$result | Export-Csv -Path 'Path\To\The\zabbix_results.csv' -NoTypeInformation

Output:

Host      Severity
----      --------
Server-01 Average 
Server-02 High

Regex details:

Host:</b>                Match the characters “Host:</b>” literally
\s                       Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
   *                     Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
(?<host>                 Match the regular expression below and capture its match into backreference with name “host”
   [^<]                  Match any character that is NOT a “<”
      +                  Between one and unlimited times, as many times as possible, giving back as needed (greedy)
)
<br><b>Severity:</b>     Match the characters “<br><b>Severity:</b>” literally
\s                       Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
   *                     Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
(?<severity>             Match the regular expression below and capture its match into backreference with name “severity”
   [^<]                  Match any character that is NOT a “<”
      +                  Between one and unlimited times, as many times as possible, giving back as needed (greedy)
)
<br>                     Match the characters “<br>” literally

As requested two more properties are added to the result:

$zabbixAlert   = Get-ZabbixAlert

$regex = [regex] 'Host:</b>\s*(?<host>[^<]+)<br><b>Severity:</b>\s*(?<severity>[^<]+)<br>'
$match = $regex.Match($zabbixAlert.message)
$result = while ($match.Success) {
    [PsCustomObject]@{
        # Chennai (India - Tamil Nadu) has an UTC offset of +5:30 hours (5.5)
        # Time     = '{0:dd-MM-yyyy HH:mm}' -f (ConvertFrom-Epoch $zabbixAlert.clock).Addhours(5.5)
        # I think using '.ToLocalTime()' is a lot easier:
        Time     = '{0:dd-MM-yyyy HH:mm}' -f (ConvertFrom-Epoch $zabbixAlert.clock).ToLocalTime()
        Alert    = $zabbixAlert.subject
        Host     = $match.Groups['host'].Value
        Severity = $match.Groups['severity'].Value
    }
    $match = $match.NextMatch()
} 

# display as table on screen
$result | Format-Table -AutoSize

# export to a CSV file
$result | Export-Csv -Path 'Path\To\The\zabbix_results.csv' -NoTypeInformation

Upvotes: 1

Related Questions