Quick and Dirty Web Site Monitoring with PowerShell
The other day Mark noticed that redirections for our https://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("https://www.sysinternals.com/")
$endTime = get-dateif ($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"] = "https://www.sysinternals.com"
$urlsToTest["TechNet Redirect"] = "https://www.microsoft.com/sysinternals"
$urlsToTest["Sysinternals Home"] = "https://www.microsoft.com/technet/sysinternals/default.mspx"
$urlsToTest["Sysinternals Forum"] = "https://forum.sysinternals.com"
$urlsToTest["Sysinternals Blog"] = "https://blogs.technet.com/sysinternals"
$urlsToTest["Sysinternals Downloads"] = "https://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-dateif ($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)
}
}
}
Comments
Anonymous
January 01, 2003
Several months ago I stumbled upon PowerGadgets and have been finding more and more uses for it ever since. I was initially intrigued by the ability to run powershell scripts but didn't have any ...Anonymous
January 01, 2003
Creating a management dashboard with PowerGadgets and PowerShellAnonymous
January 01, 2003
Otto Helweg has a cool blog entry about how he uses PowerShell to monitor Web Sites HERE . This isn'tAnonymous
October 24, 2007
How would you modify this script to send credentials if your website is secured?Anonymous
December 05, 2007
Hello Otto, Thank you for this cool post. It recently helped me out with a powershell project I was working on that needed email confirmation. To help others, I wrote up a post on <a href="http://www.searchmarked.com/windows/how-to-send-an-email-using-a-windows-powershell-script.php> How to send an email using a Windows Powershell script</a> Thanks again for sharing this information! -Harley Stagner <a href="http://www.searchmarked.com>http://www.searchmarked.com</a>Anonymous
December 22, 2007
thank you for the post. it saves me from using of paid servicesAnonymous
April 21, 2008
For me, running script in example 1 returns success and the subsequent results give a fail. I've just done a straight copy and paste of your code and not changed any URLs. Any idea why?