As many of you know, one of the things I’m doing these days is helping run The Experts Community web site. As such I need to make sure it is up and running. I also like to make sure my blog and a few other sites are responding to HTTP requests. To meet this need I put together a PowerShell function to test a web site and determine if it is running or not.
There are no cmdlets from Microsoft for testing web site connectivity. However, there is a .NET class called System.Net.WebRequest. I put together a short 2.0 function that uses this class and returns a custom object to the pipeline.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
<span style="color: #00008b">Function</span> <span style="color: #8a2be2">Test-WebSite</span> <span style="color: #000000">{</span> <span style="color: #a9a9a9">[</span><span style="color: #add8e6">cmdletBinding</span><span style="color: #000000">(</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span> <span style="color: #00008b">Param</span> <span style="color: #000000">(</span> <span style="color: #a9a9a9">[</span><span style="color: #add8e6">Parameter</span><span style="color: #000000">(</span> <span style="color: #000000">ValueFromPipeline</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$True</span><span style="color: #a9a9a9">,</span><span style="color: #000000">Position</span><span style="color: #a9a9a9">=</span><span style="color: #800080">0</span><span style="color: #a9a9a9">,</span><span style="color: #000000">Mandatory</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$True</span><span style="color: #a9a9a9">,</span> <span style="color: #000000">HelpMessage</span><span style="color: #a9a9a9">=</span><span style="color: #8b0000">"The URL to test. Include http:// or https://"</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span> <span style="color: #008080">[string]</span><span style="color: #ff4500">$url</span> <span style="color: #000000">)</span> <span style="color: #00008b">Begin</span> <span style="color: #000000">{</span> <span style="color: #0000ff">Write-Verbose</span> <span style="color: #8b0000">"Begin function"</span> <span style="color: #000000">}</span> <span style="color: #00008b">Process</span> <span style="color: #000000">{</span> <span style="color: #0000ff">Write-Verbose</span> <span style="color: #8b0000">"Requesting $url"</span> <span style="color: #ff4500">$wr</span><span style="color: #a9a9a9">=</span><span style="color: #008080">[system.net.webrequest]</span><span style="color: #a9a9a9">::</span><span style="color: #000000">Create</span><span style="color: #000000">(</span><span style="color: #ff4500">$url</span><span style="color: #000000">)</span> <span style="color: #006400">#set timeout to 7 seconds</span> <span style="color: #ff4500">$wr</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Timeout</span><span style="color: #a9a9a9">=</span><span style="color: #800080">7000</span> <span style="color: #ff4500">$start</span><span style="color: #a9a9a9">=</span><span style="color: #0000ff">Get-Date</span> <span style="color: #00008b">Try</span> <span style="color: #000000">{</span> <span style="color: #ff4500">$response</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$wr</span><span style="color: #a9a9a9">.</span><span style="color: #000000">GetResponse</span><span style="color: #000000">(</span><span style="color: #000000">)</span> <span style="color: #00008b">if</span> <span style="color: #000000">(</span><span style="color: #ff4500">$response</span><span style="color: #000000">)</span> <span style="color: #000000">{</span> <span style="color: #0000ff">Write-Verbose</span> <span style="color: #8b0000">"Response returned"</span> <span style="color: #ff4500">$Status</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$response</span><span style="color: #a9a9a9">.</span><span style="color: #000000">StatusCode</span> <span style="color: #ff4500">$StatusCode</span><span style="color: #a9a9a9">=</span><span style="color: #000000">(</span><span style="color: #ff4500">$response</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Statuscode</span> <span style="color: #a9a9a9">-as</span> <span style="color: #008080">[int]</span><span style="color: #000000">)</span> <span style="color: #000000">}</span> <span style="color: #000000">}</span> <span style="color: #00008b">Catch</span> <span style="color: #008080">[system.net.webexception]</span> <span style="color: #000000">{</span> <span style="color: #0000ff">Write-Verbose</span> <span style="color: #8b0000">"Failed to get a response from $url"</span> <span style="color: #0000ff">Write-Warning</span> <span style="color: #8b0000">"Failed to get a response from $url"</span> <span style="color: #ff4500">$status</span> <span style="color: #a9a9a9">=</span> <span style="color: #ff4500">$_</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Exception</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Response</span><span style="color: #a9a9a9">.</span><span style="color: #000000">StatusCode</span> <span style="color: #ff4500">$statuscode</span> <span style="color: #a9a9a9">=</span> <span style="color: #000000">(</span> <span style="color: #ff4500">$_</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Exception</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Response</span><span style="color: #a9a9a9">.</span><span style="color: #000000">StatusCode</span> <span style="color: #a9a9a9">-as</span> <span style="color: #008080">[int]</span><span style="color: #000000">)</span> <span style="color: #000000">}</span> <span style="color: #ff4500">$end</span><span style="color: #a9a9a9">=</span><span style="color: #0000ff">Get-Date</span> <span style="color: #ff4500">$timespan</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$end</span><span style="color: #a9a9a9">-</span><span style="color: #ff4500">$start</span> <span style="color: #ff4500">$ResponseMS</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$timespan</span><span style="color: #a9a9a9">.</span><span style="color: #000000">TotalMilliseconds</span> <span style="color: #0000ff">Write-Verbose</span> <span style="color: #8b0000">"status is $status"</span> <span style="color: #0000ff">Write-Verbose</span> <span style="color: #8b0000">"statuscode is $statuscode"</span> <span style="color: #0000ff">Write-Verbose</span> <span style="color: #8b0000">"timer is $responseMS"</span> <span style="color: #ff4500">$obj</span><span style="color: #a9a9a9">=</span><span style="color: #0000ff">New-Object</span> <span style="color: #8a2be2">PSObject</span> <span style="color: #000080">-Property</span> <span style="color: #000000">@{</span> <span style="color: #000000">DateTime</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$start</span> <span style="color: #000000">URL</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$url</span> <span style="color: #000000">Status</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$status</span> <span style="color: #000000">StatusCode</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$statuscode</span> <span style="color: #000000">ResponseMS</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$ResponseMS</span> <span style="color: #000000">}</span> <span style="color: #0000ff">Write-Output</span> <span style="color: #ff4500">$obj</span> <span style="color: #000000">}</span> <span style="color: #006400">#end Process</span> <span style="color: #00008b">End</span> <span style="color: #000000">{</span> <span style="color: #0000ff">Write-Verbose</span> <span style="color: #8b0000">"End function"</span> <span style="color: #000000">}</span> <span style="color: #000000">}</span> <span style="color: #006400">#end function</span> |
The function takes a URL to test and it can be piped. Using a Try/Catch construct the function attempts to get a response from the site. If it fails, then a System.Net.WebException object is caught so I can grab the status code (eg 404 or 500).
The .NET class doesn’t include a property to capture how long the response took, at least not that I can discover. So instead I simply get the time, attempt the request, get the time again and calculate the difference. Close enough for my needs. FInally, the function writes a custom object to the pipeline using New-Object.
When the function is loaded you can run it like this:
PS C:\> test-website http://jdhitsolutions.com/blog
ResponseMS : 253.0145
StatusCode : 200
Status : OK
URL : http://jdhitsolutions.com/blog
DateTime : 4/7/2010 11:04:30 AM
With this in place, I then turned to the notification process. Windows PowerShell 2.0 includes a cmdlet, Send-MailMessage, which can deliver an SMTP message. My script runs through a list of URLs, saves the objects to a variable, which I then parse out to build a message string. Each URL has its own message which is temporary stored in an array. Then the array is converted to a string and used as the message body for my email notification.
#build message string for email
$data | foreach {
$m=("{0} {1} {2} ({3}) {4} milliseconds" -f `
|
1 2 3 4 5 6 7 8 9 10 |
<span style="color: #ff4500">$_</span><span style="color: #a9a9a9">.</span><span style="color: #000000">DateTime</span><span style="color: #a9a9a9">,</span><span style="color: #ff4500">$_</span><span style="color: #a9a9a9">.</span><span style="color: #000000">url</span><span style="color: #a9a9a9">,</span><span style="color: #ff4500">$_</span><span style="color: #a9a9a9">.</span><span style="color: #000000">status</span><span style="color: #a9a9a9">,</span><span style="color: #ff4500">$_</span><span style="color: #a9a9a9">.</span><span style="color: #000000">StatusCode</span><span style="color: #a9a9a9">,</span><span style="color: #ff4500">$_</span><span style="color: #a9a9a9">.</span><span style="color: #000000">ResponseMS</span><span style="color: #000000">)</span> <span style="color: #0000ff">Write-Verbose</span> <span style="color: #8b0000">"Building message string"</span> <span style="color: #0000ff">Write-Verbose</span> <span style="color: #ff4500">$m</span> <span style="color: #ff4500">$msg</span><span style="color: #a9a9a9">+=</span><span style="color: #ff4500">$m</span> <span style="color: #000000">}</span> <span style="color: #006400">#send mail response</span> <span style="color: #0000ff">Write-Verbose</span> <span style="color: #8b0000">"Sending mail message"</span> <span style="color: #0000ff">Send-MailMessage</span> <span style="color: #000080">-To</span> <span style="color: #ff4500">$to</span> <span style="color: #000080">-From</span> <span style="color: #ff4500">$from</span> <span style="color: #000080">-Subject</span> <span style="color: #ff4500">$subject</span> <span style="color: #000000">` </span><span style="color: #000080">-Body</span> <span style="color: #000000">$(</span><span style="color: #ff4500">$msg</span> <span style="color: #a9a9a9">|</span><span style="color: #0000ff">out-string</span><span style="color: #000000">)</span> <span style="color: #000080">-SmtpServer</span> <span style="color: #ff4500">$smtpServer</span> <span style="color: #000080">-credential</span> <span style="color: #ff4500">$mailcred</span> |
Depending on your SMTP server configuration you may or may not need to specify a credential. Your SMTP server may also need some minor reconfiguration depending on your network.
The last step was to simply create a scheduled task to run my PowerShell script:
powershell.exe -noprofile -noninteractive -file c:\scripts\ScheduledWebCheck.ps1
Now I get an hourly report that lets me know the web site status, which thankfully is almost always up.

Jeff see:
http://www.scriptinganswers.com/forum2/forum_posts.asp?TID=3744
Tis might be of interest for a future blog as your above bolg solves a couple of problems but does not discover the rediredcted URL. I looked for a quick way in VBS but didn’t find one. Haben’t looked at PowerShell for a solution.
Also the following might be interesting for your IIS Admin blogs. It’s AD/PowerShell/IIS related.
http://www.scriptinganswers.com/forum2/forum_posts.asp?TID=3757
GL