Use PowerShell to Monitor RSS/Atom Feed

Use PowerShell’s Invoke-WebRequest to retrieve and parse an RSS or Atom feed.

Status monitoring feeds aplenty

There are a lot of third party services that provide status monitoring updates through RSS/Atom feeds. Statuspage is a popular service that other companies use for providing this type of status monitoring feed, as well as a status page for web viewing.

For my case, I wanted to take advantage of monitoring one of these status feeds, but I wanted to do it using PowerShell so I could send email alerts and display status information within Solarwinds Orion. Here is how I used the Atom feed from DigitalOcean‘s Statuspage.

Invoke-WebRequest: PowerShell’s way to process the web

To pull down and work with DigitalOcean’s Statuspage atom feed, we will use the cmdlet
Invoke-WebRequest . Per docs.microsoft.com,
Invoke-WebRequest “gets content from a web page on the Internet.”

<content type="html">&lt;p&gt;&lt;small&gt;Nov27,23:22UTC&lt;/small&gt;&lt;br&gt;&lt;strong&gt;Update&lt;/strong&gt;-We have temporarily disabled the contact form whilewe work to resolve the issues causing delays with ticket creation.Untilthe issue is fixed,please email contact@digitalocean.com or submitaticket directly through the control panel ifyou need assistance from our support team.We appreciate your patience,and apologize forany inconveniences.&lt;/p&gt;&lt;p&gt;&lt;small&gt;Nov27,18:40UTC&lt;/small&gt;&lt;br&gt;&lt;strong&gt;Investigating&lt;/strong&gt;-We are investigating an issue wheremessages submitted through our contact form are experiencing delays creating tickets inour support center.This issue may lead toadelay inresponse time from our support team.As we work to correct this issue,we recommend that users inneed of support log into the control panel to submit tickets,or email us at contact@digitalocean.com.&lt;/p&gt;</content>

</entry>

...

Return Invoke-WebRequest result to $Response variable

Using this URL, we will now request the content from the URL and store the response in a PowerShell variable for further processing.

Note that we used the argument
-UseBasicParsing . By default, the
Invoke-WebRequest cmdlet leverages Internet Explorer. If the computer we are running the script on (and this script is intended to run on a server) doesn’t have Internet Explorer installed, this argument allows us to still return the HTML content.

I add the argument
-ContentType"application/xml" specifies the content type of the request. This isn’t necessarily required; if you ran the command above without this it would still return the right content, but I feel it is more complete and makes it easier to understand.

Exploring $Response object

Let’s take a look at $Response. You’ll see we get properties StatusCode and StatusDescription which tell us the response was OK. You then see Content contains XML, which is the same XML that we see when we navigate directly to the Atom feed URL. Because it is all XML, we can easily parse it.

Parsing feed entries from XML

Now we will parse the XML to identify the entries. We cast
$Response.Content as XML and store it in
$FeedXml . We then iterate through the entries we find within the XML content, and in this example adding anything updated within the last 24 hours to an array. We use PSCustomObject to create an object to store the information from the entry within the array.

PowerShell

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

$FeedXml=[xml]$Response.Content

$Entries=@()

$Now=Get-Date

# Exract recent entries (currently set for updated within the last 24 hours)

ForEach($Entryin$FeedXml.feed.entry){

If(($Now-[datetime]$Entry.updated).TotalHours-le24){

$Entries+=[PSCustomObject]@{

'Id'="status.digitalocean.com - "+($Entry.id).Remove(0,24)

'Updated'=[datetime]$Entry.updated

'Title'=$Entry.title

'Content'=$Entry.content.'#text'

}

}

}

Sending email alert for recent feed entries

The reference script was intended to check the feed every five minutes and send an email alert for each updated entry within the last five minutes. We iterate through the array again to identify those recent items and send an email using
Send-MailMessage . (NOTE: Opportunity for optimization here – this could be incorporated into the initial
ForEach iteration).

PowerShell

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

# Send email notifications for entries updated in the last 5 minutes.

ForEach($Entryin$Entries){

If(($Now-[datetime]$Entry.updated).TotalMinutes-le5){

$Params=@{

'Body'=$Entry.Content

'BodyAsHtml'=$true

'From'="alert@example.com"

'SmtpServer'="smtp.example.com"

'Subject'=$Entry.Id+" - "+$Entry.Title

'To'="alerts@example.com"

}

# Send notifications

Send-MailMessage@Params

}

}

Here is an example snippet of how an email alert generated from this feed:

Alert email example

Full Solarwinds component monitor for atom feed

In this post we covered bits of the Solarwinds component monitor as it related to requesting an atom feed and parsing it. For the full compoent monitor script, refer to the Github Gist link in the Reference section below. There is plenty of opportunities for optimization, but in its current form it is providing basic capabilities that we sought.