Archives for the Month of August, 2014

Creating an Easy PowerShell Uptime Monitor

In a recent post, I blogged some data based on an uptime monitor I put together when I started having problems with my (then) web hosting platform.

Here’s how it works.

The first step is a script, Test-Uri. This essentially runs the Invoke-WebRequest cmdlet and captures the important details: Time, Uri, Status Code, Status Description, Response Length (so you can detect drastic content changes or incomplete responses), and Time Taken.

 

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
##############################################################################
##
## Test-Uri
##
## From Windows PowerShell Cookbook (O'Reilly)
## by Lee Holmes (http://www.leeholmes.com/guide)
##
##############################################################################

<#
 
.SYNOPSIS
 
Connects to a given URI and returns status about it: URI, response code,
and time taken.
 
.EXAMPLE
 
PS > Test-Uri bing.com
 
Uri : bing.com
StatusCode : 200
StatusDescription : OK
ResponseLength : 34001
TimeTaken : 459.0009
 
#>

param(
   
## The URI to test
    $Uri
)

$request = $null
$time
 = try
{
   
## Request the URI, and measure how long the response took.
$result = Measure-Command { $request = Invoke-WebRequest -Uri $uri
 }
   
$result.
TotalMilliseconds
}

catch
{
   
## If the request generated an exception (i.e.: 500 server
    ## error or 404 not found), we can pull the status code from the
    ## Exception.Response property
    $request = $_.Exception.
Response
   
$time = -1
}

$result = [PSCustomObject] @{
    Time 
= Get-Date
;
    Uri 
= $uri
;
    StatusCode 
= [int] $request.
StatusCode;
    StatusDescription 
= $request.
StatusDescription;
    ResponseLength 
= $request.
RawContentLength;
    TimeTaken 
= $time
;
}

$result

 

The second step automates the invocation of the Test-Uri command, sending its output into a CSV. To do this, you use the Register-ScheduleJob cmdlet. Here’s an example to test your blog every hour:

001
002
003
004
005
006
007
008
009
010
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) `
   
-RepetitionInterval (New-TimeSpan
 -Hours 1
) `
   
-RepetitionDuration ([TimeSpan]::MaxValue)

Register-ScheduledJob -Name blogMonitor -Trigger $trigger -ScriptBlock {
   
$myDocs = [Environment]::GetFolderPath("MyDocuments"
)
   
$outputPath = Join-Path $myDocs blogMonitor.csv
    Test-Uri http://www.leeholmes.com/blog | Export-Csv -Append $outputPath
}

 

As long as your computer has internet connectivity, this is a very reliable approach. And it’s not exactly “big data” – I’ve been monitoring my blog every hour since September 1, 2012 and the CSV is only 1.3MB.