A Simple App Fabric powershell monitor

Hi there. i am trying to create a simple powershell monitor, but it is slightly complicated, as it requires loading of modules, and storing credentials for a remoting session. Is this possible?

basically it is for an app fabric cache cluster, and the command on the server is just get-cacheclusterhealth this then returns some results:

PS C:\Windows\System32\WindowsPowerShell\v1.0\

tion> Get-Cacheclusterhealth

Cluster health statistics

=========================

HostName = **************

-------------------------

    NamedCache = *************

        Healthy              = 25.00

        UnderReconfiguration = 0.00

        NotPrimary           = 0.00

        NoWriteQuorum        = 0.00

        Throttled            = 0.00

    NamedCache = ****************

        Healthy              = 25.00

        UnderReconfiguration = 0.00

        NotPrimary           = 0.00

        NoWriteQuorum        = 0.00

        Throttled            = 0.00

    NamedCache = ***************

        Healthy              = 25.00

        UnderReconfiguration = 0.00

        NotPrimary           = 0.00

        NoWriteQuorum        = 0.00

        Throttled            = 0.00

    NamedCache = **********

        Healthy              = 25.00

        UnderReconfiguration = 0.00

        NotPrimary           = 0.00

        NoWriteQuorum        = 0.00

        Throttled            = 0.00

If there is a 25 next to any of the 'throttled' section, i want it to notify.

Any thoughts on the best route to take on this?

i've tried to import the modules onto the orion server, but the get-cacheclusterhealth command doesn't look like it can be run using a -host or anything.

I can run the script in the edit script box in the template, but the above is the output - i'm just not sure on the syntax of the unique identifers i need in the script - ideally, it would be that 'throttled' would have any other value rather than 0.00

stat.throttled = 0.00

Message.throttled = Throttled

Or something. not really following it here: The Basics of PowerShell (part 3) 

  • You'll need to parse the results of the output to get it to work as a component monitor. Probably pump the detail into an array and then a foreach to search through looking for throttled.

    What you'd write-host to the screen would be

    statistic.throttled = 0

    message.throttled = "some text here"

    There are guidelines in this article.

    SAM Script Component Monitors - Everything you need to know

  • thanks - i'll have a read, i think i thought this would be easy emoticons_happy.png

  • OK, so here is what i think  have to do.

    I want to store the output of my PS command in a variable, so

    $raw = get-cacheclusterhealth

    Then i need to match the text

    $throttledmatches = select-string "Throttled" *= [0-9\.]+" -input $raw -all matches | foreach {$_.matches}


    I then need just the numbers

    $nums = select-string "[0-9\.]+" -input $throttledMatches -allmatches | foreach {$_.matches}

    Then i can do $num[0] for my first match.

    Does that sound right? It works correctly whilst i was working with just the output (i loaded it in from a text file) but i can't seem to write-host on the $raw it doesn't return. If i just type $raw, it does...

    ugh.

    Any thoughts?

  • Seems like you're on the right track. Not sure why it wouldn't let you write-host $raw. Are you building this in powershell ISE? That is typically where I build my scripts out. Once the script is 100% work is when i transfer it SAM.

    Maybe try in just a powershell window:

    Get-CacheClusterHealth | Out-File results.txt

    Post the results of the .txt file?

  • yeah its weird, the output is completely different to if i output it to a file.

    PS C:\Windows\system32> $raw = get-cacheclusterhealth

    PS C:\Windows\system32> write-host $raw

    Microsoft.ApplicationServer.Caching.Commands.ClusterHealth

    So thats weird.

    If i output to a file, it formats it as in my original post. I don't really want to have to output and import, as i'll be doing this every 5 minutes

    strange huh?

  • Get-CacheClusterHealth is returning a custom object type, not a string, which is why you might end up getting some odd behavior.  Because it's returning an object, you don't have to treat it like a string, and parse the response using select-string.  Unfortunately we decommissioned our AppFabric cache farm about 6 months ago so I have no test platform to work with.  You can do some basic tests and you can actually make your output more useful.  For example if you use the Get-Member function, you can see how the object is constructed (MSDN page is rather light on the details).

    Get-CacheClusterHealth | Get-Member

    This should return some handy information, if you want to paste it here, we can take a look, but having a guess, the values in the output in your raw data probably are individual fields.  With that in mind, if you are just after an alert when any of the caches are throttled, you can probably use something like this:

    $caches = Get-CacheClusterHealth | ?{ $_.Throttled -gt 0 }

    $msg = ($caches).NamedCache -join ';'

    $stats = ($caches | Sort -Descending Throttled | Select -First).Throttled

    "Message: $msg"

    "Statistic: $stats"

    To turn this into "English", we're returning all the caches that have a Throttled value greater than 0.  We're then taking their names and putting them in the $msg variable and joining them with a ;.  This is user readable data so it might help you identify quickly in an alert if one particular cache is an issue.  The $stats variable takes the cache with the highest throttled value and puts that in the statistics.  Then we throw the output to SolarWinds using the Message/Statistic flags.

  • Agreed, i wouldn't output/input files either. Just curious what it showed.

    Try changing the $raw line to
    $raw = $(get-cacheclusterhealth)

    and see if write-host shows anything. It also might have stored $raw as an array. so this might work

    Foreach ( $item in $raw ) {

    Write-Host $item

    }

  • $throttledmatches = select-string "Throttled" *= [0-9\.]+" -input $raw -all matches | foreach {$_.matches}

    $nums = select-string "[0-9\.]+" -input $throttledMatches -allmatches | foreach {$_.matches}

    You can actually reduce these 2 lines into a single command by using "captures".  This essentially allows you to pull out specific parts of the matches.

    $raw = Get-CacheClusterHealth

    $throttled = $raw | select-string 'Throttled\s+=\s+(\d+\.\d+)' -AllMatches | %{ $_.Matches }

    Your variable $throttled now looks like multiples of this:

    Groups   : {Throttled            = 0.00, 0.00}

    Success  : True

    Captures : {Throttled            = 0.00}

    Index    : 536

    Length   : 27

    Value    : Throttled            = 0.00

    Groups contains the matching parts, and specific captures.  In this case, the select-string command matched the line, but if you look at groups, it shows 2 different objects, which we can break down even further.

    Success  : True

    Captures : {Throttled            = 0.00}

    Index    : 309

    Length   : 27

    Value    : Throttled            = 0.00

    Success  : True

    Captures : {0.00}

    Index    : 332

    Length   : 4

    Value    : 0.00

    So now we have a quick access to the numeric value, for example:

    $throttled[0].Groups[1].Value

    This returns the first cache entry, and the numeric value.  You can use a foreach loop to walk through each of the caches as part of $throttled.

  • Guys this is absolutely brilliant information thank you. I won't get a chance to try it out until Monday, but appreciate the help.