How to monitor for event logs and use a script to modify the output – a composite datasource


 

A common request I hear is the customer wants to monitor for events in a Windows Event log.  That part is easy.  We have simple event rules and monitors for that activity.

However – what if the data in the event log needed to be parsed, or modified in some way, before passing to the alert?

 

For instance, I had a customer who needs to monitor for an event from a central server - backup software platform, about job failures from backup clients.  The event is just a single parameter, a big blob of text that has all the data, and the FQDN of the client is in the event description, but surrounded by a lot of other information. 

 

The challenge is – that for ticketing, the customer needs to place ONLY the FQDN of the CLIENT machine (which is in the event body) into a custom field of an alert.

 

SCOM doesn’t have any good data manipulation capability in the native modules, so in this case we will execute a script in response to the event.  We do this by creating a composite datasource, combining the event log module and the script probe action module.

When an event shows up that matches our criteria, we then execute a script to parse the event description, and create a propertybag in order to output this customized data to the Alert write action.

Obviously – one must take care not to put something like this in place for events that might flood the log, because the SCOM agent will try and run a script for each and every event, which could overwhelm the system.  I actually tested this with a pretty significant event flood, and it was not a big deal at all, the system kept up very nicely.

 

For my “test” event – I have created a block of text with the FQDN of the remote client machine in the body of the description:

Log Name:      Application
Source:        TEST
Date:          4/1/2016 5:13:47 PM
Event ID:      888
Computer:      RD01.opsmgr.net
Description:
foo db01.opsmgr.net foo

Then I wrote a simple script to parse this event and gather the second block of text, which will reliably contain my FQDN:

 

''''''''''''''''''''''''''''''' ' ' Basic SCOM vbscript to accept event data and parse/modify it for ouput via propertybag ' ''''''''''''''''''''''''''''''' Option Explicit Dim oAPI, oBag, sParam1, StartTime, EndTime, ScriptTime, CompNameArr, CompName 'Capture script start time StartTime = Now 'Gather the argument passed to the scriptand set to variable sParam1 = WScript.Arguments(0) 'Split the event data into multiple delimited strings in an array CompNameArr = split(sParam1," ") 'Assume the FQDN is always the 2rd "word" in the event data CompName = CompNameArr(1) 'Load the SCOM script API and propertybag Set oAPI = CreateObject("MOM.ScriptAPI") Set oBag = oAPI.CreatePropertyBag() 'Add the CompName into a propertybag oBag.AddValue "CompName", CompName oBag.AddValue "EventDescription", SParam1 'Return the bag for output oAPI.Return(oBag) 'Capture script runtime EndTime = Now ScriptTime = DateDiff("s", StartTime, EndTime) 'Log event with script outputs and runtime Call oAPI.LogScriptEvent("EventParse.vbs from Example.EventAndScript.DS", 9877, 0, "Event Data Passed to script = " & sParam1 & " -- Output after parsing for CompName = " & CompName & " -- Script Execution Completed in " & ScriptTime & " seconds") Wscript.Quit

 

So first off – we need to create the data source.  The easiest tool for creating Composite data sources is the SCOM 2007 R2 Authoring Console.  I’ll just show snippets of XML that you can forklift into your own MP’s:

 

<DataSourceModuleType ID="Example.EventAndScript.DS" Accessibility="Internal" Batching="false"> <Configuration> <xsd:element minOccurs="1" name="LogName" type="xsd:string" /> <xsd:element minOccurs="1" name="EventID" type="xsd:integer" /> <xsd:element minOccurs="1" name="EventSource" type="xsd:string" /> </Configuration> <ModuleImplementation Isolation="Any"> <Composite> <MemberModules> <DataSource ID="EventDS" TypeID="Windows!Microsoft.Windows.EventProvider"> <ComputerName /> <LogName>$Config/LogName$</LogName> <Expression> <And> <Expression> <SimpleExpression> <ValueExpression> <XPathQuery Type="UnsignedInteger">EventDisplayNumber</XPathQuery> </ValueExpression> <Operator>Equal</Operator> <ValueExpression> <Value Type="UnsignedInteger">$Config/EventID$</Value> </ValueExpression> </SimpleExpression> </Expression> <Expression> <SimpleExpression> <ValueExpression> <XPathQuery Type="String">PublisherName</XPathQuery> </ValueExpression> <Operator>Equal</Operator> <ValueExpression> <Value Type="String">$Config/EventSource$</Value> </ValueExpression> </SimpleExpression> </Expression> </And> </Expression> </DataSource> <ProbeAction ID="ScriptDS" TypeID="Windows!Microsoft.Windows.ScriptPropertyBagProbe"> <ScriptName>EventParse.vbs</ScriptName> <Arguments>"$Data/Params/Param[1]$"</Arguments> <ScriptBody><![CDATA[ ''''''''''''''''''''''''''''''' ' ' Basic SCOM vbscript to accept event data and parse/modify it for ouput via propertybag ' ''''''''''''''''''''''''''''''' Option Explicit Dim oAPI, oBag, sParam1, StartTime, EndTime, ScriptTime, CompNameArr, CompName 'Capture script start time StartTime = Now 'Gather the argument passed to the scriptand set to variable sParam1 = WScript.Arguments(0) 'Split the event data into multiple delimited strings in an array CompNameArr = split(sParam1," ") 'Assume the FQDN is always the 2rd "word" in the event data CompName = CompNameArr(1) 'Load the SCOM script API and propertybag Set oAPI = CreateObject("MOM.ScriptAPI") Set oBag = oAPI.CreatePropertyBag() 'Add the CompName into a propertybag oBag.AddValue "CompName", CompName oBag.AddValue "EventDescription", SParam1 'Return the bag for output oAPI.Return(oBag) 'Capture script runtime EndTime = Now ScriptTime = DateDiff("s", StartTime, EndTime) 'Log event with script outputs and runtime Call oAPI.LogScriptEvent("EventParse.vbs from Example.EventAndScript.DS", 9877, 0, "Event Data Passed to script = " & sParam1 & " -- Output after parsing for CompName = " & CompName & " -- Script Execution Completed in " & ScriptTime & " seconds") Wscript.Quit ]]></ScriptBody> <TimeoutSeconds>30</TimeoutSeconds> </ProbeAction> </MemberModules> <Composition> <Node ID="ScriptDS"> <Node ID="EventDS" /> </Node> </Composition> </Composite> </ModuleImplementation> <OutputType>System!System.PropertyBagData</OutputType> </DataSourceModuleType>

 

The above composite datasource allows a rule or monitor to call on it, and pass the three required data items to the Microsoft.Windows.EventProvider DS:  Event ID, Event Log Name, and Event source.  Obviously you could modify this as needed.

Next, the Microsoft.Windows.ScriptPropertyBagProbe is called.  I place my script in here, along with the event argument from the event DS, which I will just use "$Data/Params/Param[1]$".  When an event just contains a single parameter, everything in the event description is treated as Param 1.

In the script – I am outputting two propertybags:

1.  The original event description

2.  The parsed out “CompName” which is the fqdn I am after.

 

Next – I create my rule.  This is much easier creating from scratch using the SCOM 2007 R2 authoring console, or VSAE if you are used to that.  Most of the time I find myself just forklifting XML if I can find a close enough match doing what I want.  Here is the rule:

 

 

<Rule ID="Example.EventAndScript.Rule" Enabled="true" Target="Windows!Microsoft.Windows.Server.OperatingSystem" ConfirmDelivery="true" Remotable="true" Priority="Normal" DiscardLevel="100"> <Category>Custom</Category> <DataSources> <DataSource ID="DS" TypeID="Example.EventAndScript.DS"> <LogName>Application</LogName> <EventID>888</EventID> <EventSource>TEST</EventSource> </DataSource> </DataSources> <WriteActions> <WriteAction ID="Alert" TypeID="Health!System.Health.GenerateAlert"> <Priority>1</Priority> <Severity>2</Severity> <AlertMessageId>$MPElement[Name="Example.EventAndScript.Event888.rule.AlertMessage"]$</AlertMessageId> <AlertParameters> <AlertParameter1>$Data/Property[@Name='EventDescription']$</AlertParameter1> <AlertParameter2>$Data/Property[@Name='CompName']$</AlertParameter2> </AlertParameters> <Custom1>$Data/Property[@Name='CompName']$</Custom1> </WriteAction> </WriteActions> </Rule>

 

 

VERY simple.  I pass my three required configuration items:

            <LogName>Application</LogName>
            <EventID>888</EventID>
            <EventSource>TEST</EventSource>

 

And I configured the Alert write action to output both the full event description, and the parsed FQDN to the alert description.

image

 

Furthermore – to meet the requirements of putting the FQDN in a consistent location for my Ticketing system, I put the parsed FQDN into Custom Field 1 in the alert.

image

 

Now the ticketing system can look for this and make sure the ticket is assigned to the correct server owner.

And interesting option with this kind of workflow – is that you could also potentially make the alert in SCOM “appear” as if it originated from the FQDN in the event, as long as that server has a SCOM agent installed and is part of the same management group:    How to generate an alert and make it look like it came from someone else

 

 

You can download the entire sample MP which contains everything above on TechNet gallery:

https://gallery.technet.microsoft.com/SCOM-Management-Pack-to-dec108c6


Comments (0)

Skip to main content