Once I needed to keep a close eye to a File Cluster however at this particular time no proper Monitoring Solution was in place so I decided to write my own "Poor Man's Montitoring Solution" observing the items I was interested in.

The script will continuously poll the Cluster Nodes from a given Failover Cluster using WMI and .Net System.Diagnostics.PerformanceCounter Class. If certain conditions are met a Balloon Tip will pop up in the taskbar hopefully attracting your attention. Note that you must provide Cluster Name, Disk and Network Adpater to monitor and a path to your Balloon Tip icon of choice. As for the performance impact I did not not see any, neither on my desktop nor on the target nodes. To stop the script press Ctrl+C in the console.

PowerShell
Edit|Remove
# THIS SAMPLE CODE AND ANY RELATED INFORMATION ARE PROVIDED "AS IS"   
# WITHOUT WARRANTY OF ANY KIND.  
 
# Name: cluster-health.ps1   
# Author: Frank Czepat  
# Date: 19.11.2011  
 
$arrngrp = @() 
# cluster name 
$cluname = ("vs-2003"# sample interval 
$wait = 60 
# time in ms to display balloon tips 
$not = 10000 
# network adapter to monitor 
$netpub = "microsoft virtual machine bus network adapter _2" 
# disk to monitor 
$pdisk = "0 c:" 
# notification icon 
$icon = "$env:systemroot\my.ico" 
 
# performance counter thresholds, your mileage may vary ;-) 
# non paged pool in mb warning and error for x86 systems without 3gb switch 
$nppw = 150 
$nppe = 200 
# cpu total usage percentage warning and error 
$cpuw = 80 
$cpue = 90 
# pages per sec warning and error 
$pagesw = 1000 
$pagese = 2000 
# availabe mb warning and error 
$avbytesw = 100 
$avbytese = 50 
# network adapter output queue length warning and error 
$netw = 1 
$nete = 2 
# disk current queue length warning and error 
$diskw = 3 
$diske = 5 
 
# connect to cluster or exit 
write-host "Connecting to $cluname ..." 
if (!($nodes = gwmi -"select name from mscluster_node" -namespace root\mscluster -computername $cluname -authentication packetprivacy)) {exit} 
 
# balloon tip requires system.windows.forms 
[void] [system.reflection.assembly]::loadwithpartialname("system.windows.forms"$notification = new-object system.windows.forms.notifyicon 
$notification.icon = $icon 
$notification.visible = $true  
 
# console window configuration 
$conhost = get-host 
$window = $conhost.ui.rawui 
 
$size = $window.buffersize 
$size.height = 5000 
$size.width = 100 
$window.buffersize = $size 
 
$size = $window.windowsize 
$size.height = 40 
$size.width = 30 
$window.windowsize = $size 
 
$window.windowtitle = "Cluster Health" 
$window.foregroundcolor = "white" 
$window.backgroundcolor = "darkblue" 
 
clear-host   
$error.clear() 
 
"`n" 
write-host "SAMPLE INTERVAL = $WAIT SECONDS" 
write-host "PRESS CTRL+C TO QUIT" 
 
# main part, do until ctrl+c 
while(1) { 
    "`n" 
    $a = $true 
    write-Host "---CTRL+C---" 
    sleep -seconds $wait 
    "`n" 
    $dat = (get-date -uFormat "%T") 
    $dat 
 
    #loop through cluster nodes 
    foreach ($node in $nodes) { 
     
    $arrngrp = @() 
    $nodestate = $null 
    $rgstate = $null 
    $nodename = $node.name 
     
    # ping current node 
    $ping = gwmi -"select statuscode from win32_pingstatus where address = '$nodename'" -authentication packetprivacy 
    $pingstate = $ping.statuscode 
     
    # ping ok  
    if ($pingstate -eq 0) { 
     
        # get current node state and performance data 
        $curstate = gwmi -"select * from mscluster_node where name ='$nodename'" -namespace root\mscluster -computername $cluname -authentication packetprivacy 
        $nodestate = $curstate.state 
         
        # state action 
        switch ($nodestate)  
            { 
               -1 { 
               write-host $nodename= Unknown -foregroundcolor red 
               $notification.showballoontip($not,$nodename,"State= Unknown",[system.windows.forms.tooltipicon]::error) ; sleep 5 
               } 
                0 { 
                write-host $nodename= Up -foregroundcolor green 
                } 
                1 { 
                write-host $nodename= Down -foregroundcolor red 
                $notification.showballoontip($not,$nodename,"State= Down",[system.windows.forms.tooltipicon]::error) ; sleep 5 
                } 
                2 { 
                write-host $nodename= Paused -foregroundcolor yellow 
                $notification.showballoontip($not,$nodename,"State= Paused",[system.windows.forms.tooltipicon]::warning) ; sleep 5 
                } 
                3 { 
                write-host $nodename= Joining -foregroundcolor yellow 
                $notification.showballoontip($not,$nodename,"State= Joining",[system.windows.forms.tooltipicon]::warning) ; sleep 5 
                } 
            } 
        # counter and countertype 
        $files = new-object system.diagnostics.performancecounter("server""files open"""$nodename# NumberOfItems32 
        $session = new-object system.diagnostics.performancecounter("server""server sessions"""$nodename# NumberOfItems32 
        $cache = new-object system.diagnostics.performancecounter("memory""system cache resident bytes"""$nodename# NumberOfItems64 
        $npp = new-object system.diagnostics.performancecounter("memory""pool nonpaged bytes"""$nodename# NumberOfItems64 
        $cpu = new-object system.diagnostics.performancecounter("processor""% processor time""_total"$nodename# Timer100NsInverse 
        $avbytes = new-object system.diagnostics.performancecounter("memory""available bytes"""$nodename# NumberOfItems64 
        $pages = new-object system.diagnostics.performancecounter("memory""pages/sec"""$nodename# RateOfCountsPerSecond32 
        $net = new-object system.diagnostics.performancecounter("network interface","output queue length"$netpub$nodename# NumberOfItems64 
        $disk =  new-object system.diagnostics.performancecounter("physicaldisk","avg. disk queue length",$pdisk ,$nodename# NumberOfItems32 
                         
        # open files: get rawvalue  
        $filesc = $files.rawvalue 
        write-host "Files Open=" $filesc -foregroundcolor green 
         
        # server sessions: get rawvalue  
        $sessionc = $session.rawvalue 
        write-host "Server Sessions=" $sessionc -foregroundcolor green 
         
        # system cache: convert rawvalue bytes to mb  
        $cachec = [int] ( $cache.rawvalue / (1024 * 1024)) 
        write-host "System Cache=" $cachec "MB" -foregroundcolor green 
         
        # non-paged pool: convert rawvalue bytes to mb 
        $nppc = [int] ( $npp.rawvalue / (1024 * 1024)) 
                         
            # threshold action 
            if ($nppc -ge $nppe) { 
                write-Host "Nonpaged Pool=" $nppc "MB" -foregroundcolor red  
                $notification.showballoontip($not,$nodename,"Nonpaged Pool $nppc MB",[system.windows.forms.tooltipicon]::error) ; sleep 5 
                } 
                 
            elseif ($nppc -ge $nppw) { 
                write-Host "Nonpaged Pool=" $nppc "MB" -foregroundcolor yellow 
                $notification.showballoontip($not,$nodename,"Nonpaged Pool $nppc MB",[system.windows.forms.tooltipicon]::warning) ; sleep 5 
                } 
             
            else { 
                write-host "Nonpaged Pool=" $nppc "MB" -foregroundcolor green 
                } 
             
        # cpu: get two values 
        $cpu.nextvalue() | out-null 
        sleep -seconds 1 
        $cpuc = [int] ($cpu.nextvalue()) 
             
            # threshold action 
            if ($cpuc -ge $cpue) { 
                write-Host "Procesor Time=" $cpuc "%" -foregroundcolor red   
                $notification.showballoontip($not,$nodename,"CPU $cpuc %",[system.windows.forms.tooltipicon]::error) ; sleep 5 
                } 
                 
            elseif ($cpuc -ge $cpuw) { 
                write-Host "Procesor Time=" $cpuc "%" -foregroundcolor yellow 
                $notification.showballoontip($not,$nodename,"CPU $cpuc %",[system.windows.forms.tooltipicon]::warning) ; sleep 5 
                } 
             
            else { 
                write-Host "Procesor Time=" $cpuc "%" -foregroundcolor green  
                } 
                 
        # Available Bytes: convert rawvalue bytes to mb  
        $avbytesc = [int] ( $avbytes.rawvalue / (1024 * 1024)) 
                     
            # threshold action 
            if ($avbytesc -le $avbytese) { 
                write-Host "Available MBytes=" $avbytesc "MB" -foregroundcolor red  
                $notification.showballoontip($not,$nodename,"Available MBytes $avbytesc MB",[system.windows.forms.tooltipicon]::error); sleep 5 
                } 
                 
            elseif ($avbytesc -le $avbytesw) { 
                write-Host "Available MBytes=" $avbytesc "MB" -foregroundcolor yellow 
                $notification.showballoontip($not,$nodename,"Available MBytes $avbytesc MB",[system.windows.forms.tooltipicon]::warning); sleep 5 
                } 
             
            else { 
                write-host "Available MBytes=" $avbytesc "MB" -foregroundcolor green 
                } 
 
        # pages: get two values 
        $pages.nextvalue() | out-null 
        sleep -seconds 1 
        $pagesc = [int] ( $pages.nextvalue()) 
                         
            # threshold action 
            if ($pagesc -ge $pagese) { 
                write-Host "Pages/sec=" $pagesc -foregroundcolor red  
                $notification.showballoontip($not,$nodename,"Pages/sec $pagesc",[system.windows.forms.tooltipicon]::error); sleep 5 
                } 
                 
            elseif ($pagesc -ge $pagesw) { 
                write-Host "Pages/sec=" $pagesc -foregroundcolor yellow 
                $notification.showballoontip($not,$nodename,"Pages/sec $pagesc",[system.windows.forms.tooltipicon]::warning); sleep 5 
                } 
             
            else { 
                write-host "Pages/sec=" $pagesc -foregroundcolor green 
                } 
         
        # network output queue length: get rawvalue  
        $netc =  $net.rawvalue 
                     
            # threshold action 
            if ($netc -ge $nete) { 
                write-Host "Network Queue Length=" $netc  -foregroundcolor red  
                $notification.showballoontip($not,$nodename,"Output Queue Length $netc",[system.windows.forms.tooltipicon]::error) ; sleep 5 
                } 
                 
            elseif ($netc -eq $netw) { 
                write-Host "Network Queue Length=" $netc  -foregroundcolor yellow 
                $notification.showballoontip($not,$nodename,"Output Queue Length $netc",[system.windows.forms.tooltipicon]::warning) ; sleep 5 
                } 
             
            else { 
                write-host "Network Queue Length=" $netc  -foregroundcolor green 
                                 
                } 
                 
        # disk: get two values 
        $disk.nextvalue() | out-null 
        sleep -seconds 1 
        $diskc = [int] ( $disk.nextvalue()) 
                         
            # threshold action 
            if ($diskc -ge $diske) { 
                write-Host "Disk Queue Length=" $diskc -foregroundcolor red  
                $notification.showballoontip($not,$nodename,"Disk Queue Length $diskc",[system.windows.forms.tooltipicon]::error) ; sleep 5 
                } 
                 
            elseif ($diskc -ge $diskw) { 
                write-Host "Disk Queue Length=" $diskc -foregroundcolor yellow 
                $notification.showballoontip($not,$nodename,"Disk Queue Length $diskc",[system.windows.forms.tooltipicon]::warning) ; sleep 5 
                } 
             
            else { 
                write-host "Disk Queue Length=" $diskc -foregroundcolor green 
                } 
                 
        "`r" 
         
        # get groups and group state for current node 
        $nodegroups = gwmi -"select * from mscluster_nodetoactivegroup" -namespace root\mscluster -computername $cluname -authentication packetprivacy 
        $clugroups = gwmi -"select * from mscluster_resourcegroup" -namespace root\mscluster -computername $cluname -authentication packetprivacy 
             
            foreach ($nodegroup in $nodegroups) { 
                $cmpnt = $nodegroup.groupcomponent 
                if ($cmpnt -match $nodename) { 
                    $arrngrp += ($nodegroup.PartComponent) 
                    } 
                } 
             
            foreach ($group in $clugroups) {             
                $rgname = $group.name 
                if ($arrngrp -match $rgname) { 
                    $rgstate = $group.state 
                     
                    # threshold action 
                    switch ($rgstate)  
                    { 
                       -1 { 
                        write-host $rgname= Unknown -ForegroundColor red 
                        $notification.showballoontip($not,"$rgname","State= Unknown",[system.windows.forms.tooltipicon]::error); sleep 5 
                        } 
                        0 { 
                        write-host $rgname= Online -ForegroundColor green 
                        } 
                        1 { 
                        write-host $rgname= Offline -ForegroundColor red 
                        $notification.showballoontip($not,"$rgname","State= Offline",[system.windows.forms.tooltipicon]::error); sleep 5 
                        } 
                        2 { 
                        write-host $rgname= Failed -ForegroundColor red 
                        $notification.showballoontip($not,"$rgname","State= Failed",[system.windows.forms.tooltipicon]::error) ; sleep 5 
                        } 
                        3 { 
                        write-host $rgname= Partial Online -ForegroundColor red 
                        $notification.showballoontip($not,"$rgname","State= Partial Online",[system.windows.forms.tooltipicon]::error); sleep 5 
                        } 
                        4 { 
                        write-host $rgname= Pending -ForegroundColor yellow 
                        $notification.showballoontip($not,"$rgname","State= Pending",[system.windows.forms.tooltipicon]::warning); sleep 5 
                        } 
                    } 
                } 
            } 
             
        write-host "----" 
                         
        # ping failed 
        } else { 
        write-host  $nodename Ping failed Status= $pingstate -foregroundcolor red 
        $notification.showballoontip($not,$nodename,"Ping failed Status= $pingstate",[system.windows.forms.tooltipicon]::error); sleep 5 
        } 
    } 
}