Using the SDK to manipulate alerts
Posted by Jeremy D. Pavleck on November 11th, 2008
A quick disclaimer, I’m not a programmer. I’m a scripter. My code reflects that - meaning it has plenty of room for improvement. Not to mention, this is a learning aid and as such doesn’t need to be absolutely amazing. Now, on with the show.
When you’re dealing with custom alerts, and using something like the ResolutionState field to manipulate who gets what alert, you need to create a battle plan. A method of attack if you will.
One way I do this is to create my alerts with a naming convention of <Base Criteria><Sub Criteria> - My Alert.
If I wanted to create a large number of alerts for a specified department, I’d create my alert names with a base criteria of the department, like “Windows Admin Group”. I then use the subcriteria to specify what subgroup the notification should be sent to, or what particular object this alert is for. So my alert names would look something like “Windows Admin Group - CPU Usage - High CPU Usage on Special Server” or “Windows Admin Group - Exchange Admin - Low Memory Reported”. I’m using examples which you can already easily limit right now, but the methodology remains the same for custom events as well, like “Widget Support - DBA Support - The widget app has a sql fault! Oh no!”.
So, now we have the base criteria ready. And I’ll assume you’ve gone and setup the alert resolution states like I’ve shown you before. Now we’ll work on building an application that works with the SDK service to change these alert states. This method is extremely fast and robust; in testing I’ve been able to process 10,000 alerts to 15 different alert resolution states in under a minute - a time impossible to achieve via the powershell methods.
I’m building this app in VB.Net, and it’s not using much error checking. It’s fairly simple, but it’s easy to build upon and alter to your needs.
I’ve also created a domain user to authenticate to the SDK service, and added it to the OpsMgr admin group.
First we need to build the framework. Be sure to reference the 2 DLL files “Microsoft.EnterpriseManagement.OperationsManager.Common.dll” and “Microsoft.EnterpriseManagement.OperationsManager.dll” located in your <Install Dir>\System Center Operations Manager 2007\SDK Binaries folder.
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.Text
Imports System.Security
Imports Microsoft.EnterpriseManagement
Imports Microsoft.EnterpriseManagement.Administration
Imports Microsoft.EnterpriseManagement.Configuration
Imports Microsoft.EnterpriseManagement.Configuration.IO
Imports Microsoft.EnterpriseManagement.Monitoring
Module StateChanger
Sub Main()
First we’ll create a comment to use when we update the alert. This is optional, but it’s helpful to let others know how we’re doing this
Then we’ll create another string to hold our search syntax for our base criteria. I’ll keep using “Windows Admin Group” here.
Next, we’ll setup our connection the RMS. First we setup the user.
mgSettings.Domain = "YOURDOMAIN"
mgSettings.User = "UserName"
The password criteria is a tad annoying, as it uses SecureString. We can’t just blindly cast a string to SecureString, we have to do some work first.
So we first create a string with our user’s password in it.
Then we create a new SecureString object, and loop through our password Appending each character from our plain password to it. Voila, a securestring password. Woohoo!
For Each chr as Char In myPlainPassword
securePass.AppendChar(chr)
Next
NOW we can assign that to our password.
Now we can actually connect to the RMS.
Now we search for all the alerts that match our base “Windows Admin Group” criteria with a res state of 0.
We first take the baseCriteria string and convert it to a MonitoringAlertCriteria object, then use that to fetch all the matching alerts.
Dim alerts As ReadOnlyCollection(Of MonitoringAlert) = mg.GetMonitoringAlerts(alertCriteria)
Then we loop through all of those alerts, seeing if any of those match our sub-criteria. If any do, we’ll go ahead and change it’s Resolution state and update it, adding our comment to it.
For Each Alert As MonitoringAlert In alerts
If InStr(Alert.Name, "CPU Usage", CompareMethod.Text) = 0 Then
Console.WriteLine("Found a ‘CPU Usage’ alert - ID: {0}", Alert.Id)
Alert.ResolutionState = 10
Alert.Update(comment)
ElseIf InStr(Alert.Name, "Exchange Admin", CompareMethod.Text) = 0 Then
Console.WriteLine("Found an ‘Exchange Admin’ alert - ID: {0}", Alert.Id)
Alert.ResolutionState = 11
Alert.Update(comment)
End If
Next
End If
End Sub
End Module
There you go. You’ve just written your first SDK application. You can expand it as much as you want from there! Run it every 5 minutes or so, and there you go.




December 18th, 2008 at 10:36 am
Hi Jeremy,
Using a proper program instead of powershell is a neat idea performance wise, however I really think you should invest a small amount of time in extending this to be a bit more generic for long term value.
For exampel the Name you check on, put it in a text file or DB with the corresponding resolution state you want to change it too.
No need for recompilation everytime
If your interrested give me a shout/email and i’ll give you an example of what ive done (it’s in powershell, but the procedure is the same).
Another very cool thing about using the SDK is the possibility to really extend your alert flow, say based on not only alert name but also something like repeat count.
I havent implemented thoose two lines in my PS Script yet, but it will become part of it
On a side note, I cant find any proper excuses that MS might have for not letting us work with resolution states in the overrides / rules.
It’s by far one of the greatest methods of handling alerts and escalating them between systems and operators.
BR
Søren