How to have an MP update itself using PowerShell

While this may not always be the best of ideas, you may come across the need to dynamically update an MP from time to time. There are a couple of different ways to approach this. For example, you could write a process to export the MP, make the modification directly in the XML and then reimport the MP. A second option, is to connect to the SDK and make the modification directly to the rule or monitor you wish to change. This is the approach I am going to take in this blog.

First, you need the command shell installed where ever you are going to try and do this work from (or at least the DLLs). This could also be tackled using something like C# and then the command shell wouldn’t be necessary, however, I want to be able to schedule this to run within the MP that is going to be modified (self-mutating). The command shell it is.

Step 1: Get ahold of the management pack

Step 2: Get ahold of the object you want to change (rule in this case)

Step 3: Make the change

Step 4: Commit the change

This seems easy enough. Let’s get started.

Step 1: Get a hold of the management pack

In this case, we are actually going to be modifying the rule Custom.Example.SelfMutatingMP.WriteEvent within the Custom.Example.SelfMutatingMP management pack.

Step 2: Get ahold of our rule:

Sweet, there’s our rule. The rule is currently configured to write out an event with the number 100000 in the event description. This is a parameter that is passed to simple script that utilizes the logscriptevent functionality in the MOM.ScriptApi to write out the event into the Operations Manager log every 15 minutes.

We want to change this to a 100001 event.

Here’s how the rule is currently configured:

Step 3: Make the change

Check it out – there’s our 100000!

The configuration for our write action contains the little logscriptevent script as well as the parameter that is passed to the script to be written out. All we need to do is change the parameter to 100001 and then write it back.

The configuration is actually stored as a big XML string. There are several ways we could approach making the change at this point. However, the quick and easy way at this point would be just to use the replace function available for string manipulation.

Step 4: Commit the change

That’s it. If all went well, our custom rule within SCOM now has 100001 now configured as the value that will get written out with our logscriptevent script. Let’s check:

(screen shot above is a little fuzzy – the highlighted number is 100004)

There it is! Now, all we need to do is wrap it up in a PS script, use the Microsoft.Windows.PowerShellWriteAction along with a scheduler datasource. The key with the new rule is that it needs to modify itself so that it knows what the number currently is and what it needs to change the number to in order to continue the cycle.  We can do that using the exact same code as above, only point the rule at itself!

Post implementing the mutating rule with the code above, we have a cycling MP. The MP now modifies itself on a recurring basis.

Mutate Rule (after a few cycles):

Write Event Rule (after the same number of cycles):

Done!

Mutating Script:

<ScriptName>Custom.Example.Mutate.PS1</ScriptName>
<ScriptBody>
# For SCOM 2007 – Needs to be updated to handle SCOM 2012
Param($RMS,$Number)
# Set Up
Add-PSSNapin Microsoft.EnterpriseManagement.OperationsManager.Client
cd OperationsManagerMonitoring::
New-ManagementGroupConnection $RMS
cd $RMS

#Step 1
$mp = get-managementpack -name ‘Custom.Example.SelfMutatingMP’

#Step 2
$rule = $mp.getrule(“Custom.Example.SelfMutatingMP.WriteEvent”)

#Step 3 – slightly different than above but this displays better in the blog
$waconfig = $rule.writeactioncollection[0].configuration
$waconfig = $waconfig.replace(([Int]$Number-1).tostring(),$Number.tostring())
$rule.writeactioncollection[0].configuration = $waconfig

#Step 4
$rule.status = “PendingUpdate”
$rule.reconnect($mp)
$mp.acceptchanges()

#Time to modify this rule itself

$rule = $mp.getrule(“Custom.Example.SelfMutatingMP.Mutate”)
$waconfig = $rule.writeactioncollection[0].configuration
$waconfig = $waconfig.replace($Number.tostring(),([Int]$Number+1).tostring())
$rule.writeactioncollection[0].configuration = $waconfig

$rule.status = “PendingUpdate”
$rule.reconnect($mp)
$mp.acceptchanges()
</ScriptBody>
<Parameters>
<Parameter>
<Name>RMS</Name>
<Value>RMSNameHere.Domain.Com</Value>
</Parameter>
<Parameter>
<Name>Number</Name>
<Value>100001</Value>
</Parameter>
</Parameters>

Leave a Reply