Quick and Dirty Web Site Monitoring with PowerShell

The other day Mark noticed that redirections for our http://www.sysinternals.com/ URL were intermittently failing. In order to get more objective data, I built a script that tested the URL every 5 seconds, and reported back Success or Failure as well as performance (how long it took to completely download base HTML content). I found that PowerShell provided an easy way to use the WebClient .Net object and evaluate the returned HTML content.

Don't have PowerShell? Get it here.

Example 1: Single Site Monitoring

The following example opens a URL every 5 minutes, tests the content, and measures the time it took to download the HTML for the page. Notice that all the HTML is dumped into a big fat string. The string is then searched for specific text that is known to be in the requested page. Note that this script runs forever and can be stopped with a <Ctrl> 'C'.

Example PowerShell script:

$webClient = new-object System.Net.WebClient
$webClient.Headers.Add("user-agent", "PowerShell Script")

while (1 -eq 1) {
$output = ""

$startTime = get-date
$output = $webClient.DownloadString("http://www.sysinternals.com/")
$endTime = get-date

if ($output -like "*Mark Russinovich*") {
"Success`t`t" + $startTime.DateTime + "`t`t" + ($endTime - $startTime).TotalSeconds + " seconds"
} else {
"Fail`t`t" + $startTime.DateTime + "`t`t" + ($endTime - $startTime).TotalSeconds + " seconds"
}

sleep(300)
}

 

Example 2: Monitoring and Alerting for Multiple Web Sites

This script monitors multiple URLs (or web sites), and incorporates e-mail alerting and logging. Unlike the above script, it is designed to be triggered from the Windows Task Scheduler (or some other job scheduler) rather than running forever in a loop. Notice that one of the URLs is actually a zipped file and PowerShell has no problem evaluating it as a string.

Example PowerShell script:

# Collects all named paramters (all others end up in $Args)
param($alert)

# Display Help
if (($Args[0] -eq "-?") -or ($Args[0] -eq "-help")) {
""
"Usage: SysinternalsSiteTest.ps1 -alert <address> -log"
" -alert <address> Send e-mail alerts"
" -log Log results"
""
"Example: SysinternalsSiteTest.ps1 -alert somebody@nospam.com -log"
""
exit
}

# Create the variables
$global:GArgs = $Args

$urlsToTest = @{}
$urlsToTest["Sysinternals Redirect"] = "http://www.sysinternals.com"
$urlsToTest["TechNet Redirect"] = "http://www.microsoft.com/sysinternals"
$urlsToTest["Sysinternals Home"] = "http://www.microsoft.com/technet/sysinternals/default.mspx"
$urlsToTest["Sysinternals Forum"] = "http://forum.sysinternals.com"
$urlsToTest["Sysinternals Blog"] = "http://blogs.technet.com/sysinternals"
$urlsToTest["Sysinternals Downloads"] = "http://download.sysinternals.com/Files/NtfsInfo.zip"

$successCriteria = @{}
$successCriteria["Sysinternals Redirect"] = "*Mark Russinovich*"
$successCriteria["TechNet Redirect"] = "*Mark Russinovich*"
$successCriteria["Sysinternals Home"] = "*Mark Russinovich*"
$successCriteria["Sysinternals Forum"] = "*Sysinternals Utilities*"
$successCriteria["Sysinternals Blog"] = "*Sysinternals Site Discussion*"
$successCriteria["Sysinternals Downloads"] = "*ntfsinfo.exe*"

$userAgent = "PowerShell User"
$webClient = new-object System.Net.WebClient
$webClient.Headers.Add("user-agent", $userAgent)

foreach ($key in $urlsToTest.Keys) {
$output = ""

$startTime = get-date
$output = $webClient.DownloadString($urlsToTest[$key])
$endTime = get-date

if ($output -like $successCriteria[$key]) {
$key + "`t`tSuccess`t`t" + $startTime.DateTime + "`t`t" + ($endTime - $startTime).TotalSeconds + " seconds"

if ($GArgs -eq "-log") {
$key + "`t`tSuccess`t`t" + $startTime.DateTime + "`t`t" + ($endTime - $startTime).TotalSeconds + " seconds" >> WebSiteTest.log
}
} else {
$key + "`t`tFail`t`t" + $startTime.DateTime + "`t`t" + ($endTime - $startTime).TotalSeconds + " seconds"

if ($GArgs -eq "-log") {
$key + "`t`tFail`t`t" + $startTime.DateTime + "`t`t" + ($endTime - $startTime).TotalSeconds + " seconds" >> WebSiteTest.log
}

if ($alert) {
$emailFrom = "computer@nospam.com"
$emailTo = $alert
$subject = "URL Test Failure - " + $startTime
$body = "URL Test Failure: " + $key + " (" + $urlsToTest[$key] + ") at " + $startTime
$smtpServer = "somesmtpserver.nospam.com"
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($emailFrom,$emailTo,$subject,$body)
}
}
}