DashboardSeveral 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 immediate needs that required that much power.  One of the strengths of PowerGadgets is the ability to run database queries and then to present the data using very slick graphs, guages and maps.  On Vista, these visualizations are displayed using the Windows Sidebar, however you can also use floating windows which allows PowerGadgets to be equally at home on Windows XP.

My sidebar is now littered with numerous gadgets that I use to show key application metrics, from DotNetNuke Marketplace sales figures to helpdesk work queues.  I have found that picking a few key queries allows me to monitor multiple web applications without requiring me to constantly login to a bunch of different apps.  The nice thing is that as your needs change, you can quickly add new gadgets and remove older gadgets which don't have as much meaning.  Since it takes less than 5 minutes to configure most gadgets, you feel free to create them as you need them, and get rid of them when they are no longer needed.

Recently, I found a need that could not be solved with a simple database query.  The DotNetNuke website was experiencing serious performance issues.  Team members were IM'ing me a couple of times a day to tell me that the website wasn't responding again.  There are hundreds of applications available to perform website monitoring, but I was really interested in finding a lightweight solution that I could get running quickly and modify as I needed to.  Otto Helweg from Microsoft had a quick and dirty PowerShell script for doing web site monitoring that provided a good starting point.  So I fired up PowerShell Plus and modified his script to query the DotNetNuke website and report how long it took to return the results.  His script was still too heavy and did not provide the quick visual impact that a tool like PowerGadget makes possible.  With some heavy trimming I was able to get to the essence of the script.  Since I was also interested in seeing the site performance as a graph, I added some additional code to persist the timing data to a simple text file which is then used to drive the graph.   You can see the script below.  Notice that the persistence code is actually the most complicated part of the script and that monitoring the site is actually a very trivial part of the script.

#Standard Settings
$source = "http://www.dotnetnuke.com/default.aspx"
$timingsfile = "D:\Users\Joe\Documents\PowerShell Utility Scripts\PsObject\Web\monitor.txt"
$retaincount = 90
#Check time to download page
$wc = New-Object System.Net.WebClient
$curtime = (measure-command { $content = $wc.DownloadString($source) }).TotalSeconds
#Update array values
$timings = Get-Content $timingsfile
$webtimes = New-Object System.Collections.ArrayList
switch (($timings | measure-object).Count ) 
{    
$null    {"We don't have to do anything." | Out-Null } 
#single line comment hack         
#Get-Content returns an array of string unless it is a single line    
#so when one line is present the variable is a single string    1         
{[void] $webtimes.add($timings)}        
#when multiple lines are present the variable is an array of strings    
default {[void] $webtimes.AddRange($timings)} 
}
[void] $webtimes.add($curtime)
if ($webtimes.count -gt $retaincount) { $webtimes.RemoveAt(0) }
$webtimes | Out-File 
$timingsfile
#Output array of values
$webtimes

One of the great features of PowerGadgets is the ability to schedule a script or a query to run on a set schedule.  With one setting I can have my script run every minute.  With a script in hand, I created the following gadget in less than 5 minutes, and most of that time was spent just configuring the graph features.  Now I know at a glance if our site is having serious problems.  As long as I don't have too many spikes, or (heaven forbid) a maxed out graph, then everything is just fine.  If I start to see a bunch of spikes or I see the chart stay above 30 second response times, then I know it is time for me to act.

WebMonitor

Future revisions to this script will include additional logic to send SMS messages to predefined phones whenever my site hits certain performance criteria (like 3 consecutive timeouts or 10 timeouts in a 90 minute period).  This will allow me to ensure that we can be responsive to site outages whether we are sitting in front of the computer or not.

I have asked the PowerGadget team for a couple of enhancements that I think would really enhance the usability of PowerGadgets:

1.  Allow me to define parameters for scripts in the PowerGadgets Creator.  At run-time a gadget user could open a settings page that allowed them to edit these values.  This would not require the user to know any PowerShell.  So in my example above, I would like to package this gadget (which PowerGadget already does) and allow my gadget users to customize the site they are monitoring, the file where they are storing results, or the number of results to retain without needing to edit the script.

2. Allow gadgets to have an “alarm” function – if a gauge reaches a certain level, or data on a chart meets certain criteria, then take some action.  This feature should include both simple alarms and scripted alarms.  A simple alarm might include predefined triggers like simple value comparisons, and predefined actions like sending email, or flashing the gadget window.  A scripted alarm would allow the developer to define a PowerShell script which evaluates the gadget data/context and returns a boolean.  The developer would also define a PowerShell script to be executed if an alarm event is triggered.

I urge you, if you haven't checked it out already, to give PowerGadgets a try.  You just might make your job of monitoring servers and applications much easier.

UPDATE:  Updated the script to resolve a bug when your timings file is empty or only contains one line.