All posts by Jonathan Almquist

Just pushed a huge update to scomskills > projects

Can you take 30 seconds to check it out and let me know what you think? By the way, I’m trying twitterfeed for the first time, so I apologize in advance if you see an ‘out of order’ update from me.

List of updates: user registration and sign in with OpenID and Google, Twitter Bootstrap 3 styling, HTTPS/SSL for all pages, Font Awesome icon suite, recently published content feed from various blogs (and growing), color-coded search results that indicate content age, site news and alerts on front page, and a handful of other tweaks.

I invite you to register on the site. Although there is nothing to interact with quite yet, in the coming weeks there will be some fun and useful actions you can perform on the site that should spark your interest.

Now go there and tell me what you think about the updates!

image

image

image

New site launched: scomskills > projects (search v1 is ready)

Hello there, System Center community! This is an announcement of a new site that was launched today.

http://projects.scomskills.com

The three main objectives of this site are to:

  • provide interactive tools and information to the System Center community,
  • serve as a development platform in order to share ideas and learn new things, and
  • highlight some of the work I’ve done as a marketing tool for scomskills.

It just so happens these goals share many attributes, so I pulled them together into one spot.

I’ve been working on a "search" tool, and version 1 is ready! You can check it out at http://projects.scomskills.com/search.

The next phase of the search tool will include adding functionality for users to submit different types of data from various sources directly to the indexer.

As a side note – I haven’t blogged for a while now due to several different projects going that have taken up more time than I have in a day! I’m looking forward to dedicating some time to writing more about management pack authoring and other fun stuff.

This is HUGE!

If you have tried to reach the SCOMskills blog over the past day, you would have seen the maintenance and redirect page. That’s because there has been a lot of changes happening on the back-end, but everything should be running fine now.

Here’s what has happened over the past couple days:

  • SCOMskills website moved, redesigned, and re-launched! The new design has a completely new look, is much faster under the hood, and will enable us to include more dynamic content going forward. Check out the resources section – this is where visitors will be able to access some cool stuff. We’ll even be opening up sandbox/demo portals for you to see what we’re working on. There isn’t much there quite yet, but check back often – it will be updated frequently.
  • The blog has moved from http://scomskills.com/blog to http://blog.scomskills.com. All requests will be redirected, including page links, so nothing out there in the wild will be broken. The blog theme will probably change in the near future to more closely match the website.
  • Visitors can now connect to us and other SCOM fans through several different social media outlets. If you want to stay informed about our free training videos, new blog posts, and latest developments, “like” us on Facebook, follow us on LinkedIn or Twitter, and subscribe to the YouTube channel below. Please be patient as content is rolled out to these external apps. Your support is greatly appreciated!

Facebook  Twitter  LinkedIn  Google+  YouTube

Get Recursive Group Membership

Sometimes it is necessary to not only return a list of objects contained in a group, but also return all or specific objects nested in a group at different levels. For this we can leverage a built-in store procedure that is in your Operations Manager Data Warehouse. This procedure is used under the hood for the report group object picker. I’m simply leveraging it in this example to demonstrate how to get current group membership.

This is a good example group, since it contains several nested group each containing different types of objects.

There are three parameter you can change in this example:

GroupDisplayName = name of group you want to check

LevelCount = how far to look into a nested group scenario (this can also be used to find all hosted objects of group members)

StartLevel = at which level do you want to begin returning group/object membership (e.g.; do not return membership of root group, but start at second level)

This should be executed on your Operations Manager Data Warehouse, not the operational database.

 

 

DECLARE @GroupDisplayName as varchar(max) = 'All Operations Manager Objects Group',
        @LevelCount as int = 

1

,
        @StartLevel as int = 

1

,
        @ObjectListDate as datetime = getutcdate(),
        @ObjectList as xml

SET @ObjectList = '<Data><Objects><Object Use="Containment">' + 
    convert(varchar,(
        SELECT ManagedEntityRowId 
        FROM vManagedEntity 
        WHERE displayName = @GroupDisplayName)) + 
        '</Object></Objects></Data>'

CREATE TABLE #ObjectList (ManagedEntityRowId int)
INSERT INTO #ObjectList (ManagedEntityRowId)
EXEC [Microsoft_SystemCenter_DataWarehouse_Report_Library_ReportObjectListParse]
    @ObjectList = @ObjectList,
    @StartDate = @ObjectListDate,
    @EndDate = @ObjectListDate,
    @ContainmentLevelCount = @LevelCount,
    @ContainmentStartLevel = @StartLevel

SELECT ISNULL(vme.Path,vme.DisplayName) AS DisplayName, ManagedEntityDefaultName
FROM vManagedEntity as vme inner join
    #ObjectList on #ObjectList.ManagedEntityRowId = vme.ManagedEntityRowId

DROP TABLE #ObjectList

 

 

 

If you wanted to return a history of group membership, you could replace StartDate and EndDate parameters with your desired range.

 

 

 

_

Event Description Pattern Matching (with minimal impact)

One thing to think about when authoring rules and monitors is performance, and Windows event monitoring is no exception. If you need to search for a string in an event description, and if said event description is not parameterized, this post is for you.

You could add this logic while creating a rule in the Operations console.

 

image

 

The reason you should not do this is because it’s going to require more compute time than is necessary. If the monitored event log typically has a steady stream of events written, a single event detection rule like this could create a significant processing bottleneck on the monitored computer.

This is because all filtering is happening at the data source level, which means every element in your expression filter is checked against every event that is written to the specified log on that computer. Searching for a string in the event description takes time, and this is why it’s a bad practice to implement event description processing in the data source module.

To implement event monitoring with minimal performance impact, I suggest including only these parameters in the data source criteria:

  • Event Source
  • Event Id
  • Event Level
  • Event Category
  • Event Parameter [0-..]

 

Furthermore, I suggest including only these operators in the data source criteria:

  • Equal
  • NotEqual
  • Greater
  • GreaterEqual
  • Less
  • LessEqual

 

So, how is it possible to implement pattern matching while still providing minimal processing impact?

The answer is to process pattern matching criteria in a condition detection module.

 

Wow, what a concept! Let the data source filter the simple event criteria, then move to the next module to process more complex criteria. That’s the cool thing about using System.ExpressionFilter. The workflow will exit if the expression <> true.

 

To understand this logic a little better, here is the processing sequence…

Without Condition Detection:

1. DataSource\EventDetection\Provider – match event log and logging computer (if true, move next)

2. DataSource\EventDetection\Filter – process all criteria (if true, move next)

3. WriteAction\Alert – generate an alert

 

With Condition Detection:

1. DataSource\EventDetection\Provider – match event log and logging computer (if true, move next)

2. DataSource\BasicEventDetection\Filter – process simple criteria (if true, move next)

3. ConditionDetection\FilterDescription – process complex criteria (if true, move next)

4. WriteAction\Alert – generate an alert

 

Unfortunately, it is not possible to implement the condition detection module in the Operations console. You will need to author this using the R2 Authoring Console, Visual Studio Authoring Extension, or directly in XML. I am providing a rule fragment you can add to your project using VSAE.

Similarly, you could implement this logic in an event detection monitor.

 

The below fragment detects event 101, with source TEST and event level ERROR in the Application log. If simple criteria matches, move the next module to process complex criteria (match SomePattern in the event description). Generate an alert at the end.

This rule fragment needs to be updated with your criteria and alert details. If you build it, alerts will come – and your manager will thank you.

 

 

<ManagementPackFragment SchemaVersion="2.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Monitoring>
    <Rules>
      <Rule ID="MyMp.Rule.EventDescriptionMatches" ConfirmDelivery="true" DiscardLevel="100" Enabled="true" Priority="Normal" Remotable="false" Target="Windows!Microsoft.Windows.Computer">
        <Category>Alert</Category>
        <DataSources>
          <DataSource ID="BasicEventDetection" TypeID="Windows!Microsoft.Windows.EventProvider">
            <ComputerName>$Target/Property[Type="Windows!Microsoft.Windows.Computer"]/NetworkName$</ComputerName>
            <LogName>Application</LogName>
            <Expression>
              <And>
                <Expression>
                  <SimpleExpression>
                    <ValueExpression>
                      <XPathQuery>EventSourceName</XPathQuery>
                    </ValueExpression>
                    <Operator>Equal</Operator>
                    <ValueExpression>
                      <Value>TEST</Value>
                    </ValueExpression>
                  </SimpleExpression>
                </Expression>
                <Expression>
                  <SimpleExpression>
                    <ValueExpression>
                      <XPathQuery>EventDisplayNumber</XPathQuery>
                    </ValueExpression>
                    <Operator>Equal</Operator>
                    <ValueExpression>
                      <Value>101</Value>
                    </ValueExpression>
                  </SimpleExpression>
                </Expression>
                <Expression>
                  <SimpleExpression>
                    <ValueExpression>
                      <XPathQuery>EventLevel</XPathQuery>
                    </ValueExpression>
                    <Operator>Equal</Operator>
                    <ValueExpression>
                      <Value>1</Value>
                    </ValueExpression>
                  </SimpleExpression>
                </Expression>
              </And>
            </Expression>
          </DataSource>
        </DataSources>
        <ConditionDetection ID="FilterDescription" TypeID="System!System.ExpressionFilter">
          <Expression>
            <RegExExpression>
              <ValueExpression>
                <XPathQuery>EventDescription</XPathQuery>
              </ValueExpression>
              <Operator>MatchesRegularExpression</Operator>
              <Pattern>SomePattern</Pattern>
            </RegExExpression>
          </Expression>
        </ConditionDetection>
        <WriteActions>
          <WriteAction ID="Alert" TypeID="Health!System.Health.GenerateAlert">
            <Priority>1</Priority>
            <Severity>2</Severity>
            <AlertMessageId>$MPElement[Name="MyMp.Rule.EventDescriptionMatches.AlertMessage"]$</AlertMessageId>
            <AlertParameters />
            <Suppression />
          </WriteAction>
        </WriteActions>
      </Rule>
    </Rules>
  </Monitoring>
  <Presentation>
    <StringResources>
      <StringResource ID="MyMp.Rule.EventDescriptionMatches.AlertMessage"/>
    </StringResources>
  </Presentation>
  <LanguagePacks>
    <LanguagePack ID="ENU" IsDefault="true">
      <DisplayStrings>
        <DisplayString ElementID="MyMp.Rule.EventDescriptionMatches">
          <Name>Event Description Match Alert Rule</Name>
        </DisplayString>
        <DisplayString ElementID="MyMp.Rule.EventDescriptionMatches.AlertMessage">
          <Name>Event Description Match</Name>
          <Description>Event description match pattern specified in rule configuration.</Description>
        </DisplayString>
      </DisplayStrings>
    </LanguagePack>
  </LanguagePacks>
</ManagementPackFragment>

 

 

 

 

__