OpsMgr: Monitoring File Content with a Powershell-based Monitor

><]]]°>          <°[[[><      ><]]]°>        <°[[[><       <°[[[><      ><]]]°>        <°[[[><         <°[[[><      ><]]]°>

This post features an example of a file content monitor that was created with the Powershell-based monitor (PBM) type and wizard (Download sample). 

In this example, a file content monitor to look for and alert on ASCII animals (ASCIImals ?) found in a sample file, was created.

The sample file contains the following combination of characters and was placed on a specific drive of an agent managed computer:

 image

The alert and state change recorded are as follows:

image

image

 

But what if the sample file contains a slight variation to the search pattern used, example as follows:

 image

The script used was able to do an estimate of the least amount of matches found. Hence, the alert and state change recorded are as follows:

image

image

 

<°[[[><       ><]]]°>    ><]]]°>       <°[[[><     <°[[[><        <°[[[><       ><]]]°>    ><]]]°>  <°[[[><     ><]]]°>  <°[[[><       ><]]]°>     <°[[[><      

Now, lets see how this File Content Monitor was configured:

For this Powershell-based unit monitor, the following values were used in General Properties.
Note: This monitor targets the Windows Server class, and hence will find and check the samples files located in all agent management computer of the management group.

 image

 

The Powershell script used by this monitor was modified to return its output in a Propertybag.

 image

 

Building expressions based on the value in the Propertybag and mapping monitor conditions to health states were very straight forward. The Expression Builder Pages builds expression that looks for a particular value from the Propertybag that the data source outputs (Property[@Name='State'] ).

The name of the value in the Propertybag was specified in the alert context variable: $Data/Context/Property[@Name='Description'] $

 image

 

Here is the script used:

This script searches the sample test file for combinations of characters that matches the patterns specified at the top of the script.

#Sample script start
$fileName= "c:\SampleTestFile.txt"

$fishCount = 0
$pattern4fish1 = "<*\[\[\[><"
$pattern4fish2 = "><]]]*"

$frogCount = 0
$pattern4frog1 = "@..@"
$pattern4frog2 = "(----)"
$pattern4frog3 = "\/_> <_\\"

$possumCount = 0
$pattern4possum1 = "(\\__/)"
$pattern4possum2 = "(=0.0=)"
$pattern4possum3 = '\(\"\)_\(\"\)'

$API = new-object -comObject "MOM.ScriptAPI"
$PropertyBag = $API.CreatePropertyBag()

$FullList=""
$newline = "`r`n"

if(Test-Path -path $fileName) {

###Look for fish###
select-string -path $filename -pattern $pattern4fish1 -allmatches | ForEach {$fishToLeft = 0} {$fishToLeft += $_.Matches.count}
select-string -path $filename -pattern $pattern4fish2 -allmatches | ForEach {$fishToRight = 0} {$fishToRight += $_.Matches.count}
$fishCount = $fishToLeft + $fishToRight
$FullList = "There are " + $fishCount + " fish found in " + $fileName + ", " + $fishToLeft + " looking to the left and " + $fishToRight + " looking to the right. " + $newline

###Look for possums###
select-string -path $filename -pattern $pattern4possum1 -allmatches | ForEach {$possumPart1 = 0} {$possumPart1 += $_.Matches.count}
select-string -path $filename -pattern $pattern4possum2 -allmatches | ForEach {$possumPart2 = 0} {$possumPart2 += $_.Matches.count}
select-string -path $filename -pattern $pattern4possum3 -allmatches | ForEach {$possumPart3 = 0} {$possumPart3 += $_.Matches.count}
if($possumPart1 -eq $possumPart2 -and $possumPart1 -eq $possumPart3 -and $possumPart2 -eq $possumPart3) {
$FullList += "There are " + $possumPart1 + " possums found in " + $fileName + ". " + $newline }
else {
if($possumPart1 -and $possumPart2 -and $possumPart3 -ne 0) {
[int[]] $arr = $possumPart1,$possumPart2,$possumPart3
$possumEstimate = $arr | sort-object | select -first 1
$FullList += "Guess-timating there would be at least " + $possumEstimate + " possum(s) of the required type in " + $fileName + ". " + $newline }
else
{$FullList += "No luck finding a complete possum in " + $fileName + ". " + $newline }
}

###Look for frogs###
select-string -path $filename -pattern $pattern4frog1 -allmatches | ForEach {$FrogPart1 = 0} {$FrogPart1 += $_.Matches.count}
select-string -path $filename -pattern $pattern4frog2 -allmatches | ForEach {$FrogPart2 = 0} {$FrogPart2 += $_.Matches.count}
select-string -path $filename -pattern $pattern4frog3 -allmatches | ForEach {$FrogPart3 = 0} {$FrogPart3 += $_.Matches.count}
if($FrogPart1 -eq $FrogPart2 -and $FrogPart1 -eq $FrogPart3 -and $FrogPart2 -eq $FrogPart3) {
$FullList += "There are " + $FrogPart1 + " frogs found in " + $fileName + ". " + $newline }
else {
if($FrogPart1 -and $FrogPart2 -and $FrogPart3 -ne 0) {
[int[]] $arr = $FrogPart1,$FrogPart2,$FrogPart3
$FrogGuesstimate = $arr | sort-object | select -first 1
$FullList += "Guess-timating there would be at least " + $FrogGuesstimate + " frog(s) of the required type in " + $fileName + ". " + $newline }
else
{$FullList += "No luck finding a complete frog in " + $fileName + ". " +$newline }
}

}

if($FullList -eq "")
{ $PropertyBag.AddValue("State","OK")
$PropertyBag.AddValue("Description", "Nothing found !")
}
else
{ $PropertyBag.AddValue("State","FLAG")
$PropertyBag.AddValue("Description", $FullList)
}

$PropertyBag

Points to note:

The select-string is the key cmdlet used to get the number of string matches and occurrences in the sample file. 
The sort-object cmdlet was very useful to find the smallest number in a list of integers.
Escape characters (“\”) are used to handle special characters in the string pattern.
    
    
    
    
    
   
><]]]°>       <°[[[><     <°[[[><      ><]]]°>      <°[[[><     ><]]]°>    ><]]]°>     <°[[[><       <°[[[><     ><]]]°>    ><]]]°>     <°[[[><      

 

 

Disclaimer:  

All information on this blog is provided on an as-is basis with no warranties and for informational purposes only. Use at your own risk. The opinions and views expressed in this blog are those of the author and do not necessarily state or reflect those of my employer.