Notification Subscriptions


There have been a few requests recently for more granular notification subscriptions. While this is fully supported, our UI is limited in what it exposes for users to tweak. Here is a look at the SDK and how to use it to create a subscription (and related objects).

First of all, to use subscriptions, you need to setup some auxiliary objects. In my example below, the first thing I create is an endpoint. We support Sip, Sms and Smtp. The endpoint is stored as a ModuleType in the database, although this is abstracted away by the API. The fact that it’s a module type, however, means that the name has to follow the naming restrictions for management pack elements. After the endpoint, I create an action (also a ModuleType). The action combines an endpoint with configuration that allows the format of the endpoint to be specified. In the Smtp case, this allows you to specify email properties. Finally, I create a recipient that the subscription will be targeted to.

The actual subscription involves combining all the aforementioned components and specifying the criteria by which to filter notifications. In SCOM 2007, notifications are based on alerts. You configure which alerts you want to trigger notifications by using the AlertNotChangedSubscriptionConfiguration and the AlertChangedSubscriptionConfiguration classes. These are also used for connector framework subscriptions to mark alerts for forwarding. These two classes represent criteria by which to match alerts. The first matches alert that have not changed that match the criteria while the latter matches alerts that have changed that match the criteria. Both work off a polling interval. If you look at the classes in the SDK, you will notice that you can specify groups and classes to filter by, but what I really wanted to outline here was the criteria property as this is what is really not exposed fully by the UI. The criteria has to match the schema as defined in the Microsoft.SystemCenter.Library called AlertCriteriaType. Note, you don’t need the Expression tag, that is filled in for you. In terms of which columns you can query for in the criteria, it is anything that is defined on the Alert table in the db.

EDIT: Stefan Koell has put together a great powershell example to accomplish the same task.

Here’s the code:

(Note – If the criteria is not all on one line, it doesn’t work correctly, that’s why the formatting is a bit weird below. If you select the code, the full criteria should select)

using System;

using Microsoft.EnterpriseManagement;

using Microsoft.EnterpriseManagement.Administration;

using Microsoft.EnterpriseManagement.Configuration;

using Microsoft.EnterpriseManagement.ConnectorFramework;

using Microsoft.EnterpriseManagement.Monitoring;

 

namespace Jakub_WorkSamples

{

    partial class Program

    {

        static void InsertSubscription()

        {

            // Connect to the sdk service on the local machine

            ManagementGroup localManagementGroup = new ManagementGroup(“localhost);

 

            // Setup an Smtp Endpoint

            SmtpServer smtpServer = new SmtpServer(“localhost”);

            smtpServer.PortNumber = 42;

            smtpServer.AuthenticationType =

                SmtpNotificationAuthenticationProtocol.Anonymous;

 

            // The guid is here for a unique name so this can be rerun

            SmtpNotificationEndpoint smtpEndpoint =

                new SmtpNotificationEndpoint(

                “SmtpEndpoint_” + Guid.NewGuid().ToString().Replace(‘-‘, ‘_’),

                “smtp”,

                smtpServer);

            smtpEndpoint.DisplayName = “My Smtp Endpoint”;

            smtpEndpoint.Description = “This is my Smtp Endpoint”;

            smtpEndpoint.MaxPrimaryRecipientsPerMail = 10;

            smtpEndpoint.PrimaryServerSwitchBackIntervalSeconds = 15;

 

            // This commits the endpoint into the system

            localManagementGroup.InsertNotificationEndpoint(smtpEndpoint);

 

            // Setup the Smtp Action (this includes email format)

            SmtpNotificationAction smtpNotificationAction =

                new SmtpNotificationAction(

                “SmtpAction” + Guid.NewGuid().ToString().Replace(‘-‘, ‘_’));

 

            smtpNotificationAction.Body = “Body”;

            smtpNotificationAction.Description = “Description”;

            smtpNotificationAction.DisplayName = “DisplayName”;

            smtpNotificationAction.Endpoint = smtpEndpoint;

            smtpNotificationAction.From = “Test@Test.com”;

            smtpNotificationAction.Headers.Add(

                new SmtpNotificationActionHeader(“Name”, “Value”));

            smtpNotificationAction.IsBodyHtml = false;

            smtpNotificationAction.ReplyTo = “replyto@test.com”;

            smtpNotificationAction.Subject = “my subject”;

 

            // This commits the action into the system

            localManagementGroup.InsertNotificationAction(smtpNotificationAction);

 

            // Setup a recipient

            NotificationRecipientScheduleEntry scheduleEntry =

                new NotificationRecipientScheduleEntry();

            scheduleEntry.ScheduleEntryType =

                NotificationRecipientScheduleEntryType.Inclusion;

            scheduleEntry.ScheduledDays =

                NotificationRecipientScheduleEntryDaysOfWeek.Weekdays;

            scheduleEntry.DailyStartTime =

                new NotificationRecipientScheduleEntryTime(8, 0);

            scheduleEntry.DailyEndTime =

                new NotificationRecipientScheduleEntryTime(17, 0);

 

            NotificationRecipientDevice recipientDevice =

                new NotificationRecipientDevice(“smtp”, “test@test.com”);

            recipientDevice.Name = “TestDevice”;

            recipientDevice.ScheduleEntries.Add(scheduleEntry);

 

            NotificationRecipient recipient =

                new NotificationRecipient(“RecipientName” + DateTime.Now.ToString());

            recipient.Devices.Add(recipientDevice);

            recipient.ScheduleEntries.Add(scheduleEntry);

 

            // Commits the recipient

            localManagementGroup.InsertNotificationRecipient(recipient);

 

            // Alert configuration

            AlertNotChangedSubscriptionConfiguration config =

                new AlertNotChangedSubscriptionConfiguration(

                AlertSubscriptionConfigurationType.Any);

            config.Criteria = “<SimpleExpression><ValueExpression><Property>ResolutionState</Property></ValueExpression><Operator>Equal</Operator><ValueExpression><Value>255</Value></ValueExpression></SimpleExpression>”;

            config.ExpirationStartTime = DateTime.Now;

            config.PollingIntervalMinutes = 1;

 

            // Subscription

            AlertNotificationSubscription alertChangeSubscription =

                new AlertNotificationSubscription(

                “MyNewAlertChangeSubscription” + Guid.NewGuid().ToString().Replace(‘-‘, ‘_’),

                config);

            alertChangeSubscription.DisplayName = “My Subscription”;

            alertChangeSubscription.Description = “My Subscription Description”;

            alertChangeSubscription.ToRecipients.Add(recipient);

            alertChangeSubscription.Actions.Add(smtpNotificationAction);

 

            // Commits the subscription

            localManagementGroup.InsertNotificationSubscription(alertChangeSubscription);

        }

    }

}

 


Comments (45)

  1. Denis Orlov says:

    How I can use this C+ code?

    I must make an exe file?

  2. JakubOleksy says:

    This is C# and yes, you would need to make an exe.

  3. Denis Orlov says:

    Oh, I see.

    Will it create new Subscription, new Recipient and new Notification Channel?

    Shall I have opportunity to see it in UI?

    Shall I have opportunity to change it through UI?

    Thanks

  4. JakubOleksy says:

    To answer your questions in order:

    Yes

    Yes

    Yes (depending on the complexity of the criteria, however, some things are not supported in the UI)

  5. Denis Orlov says:

    Thanks a Lot!

  6. Denis Orlov says:

    Thanks a Lot!

    I try to run this code, but get a error:

    "The type or namespace name ‘EnterpriseManagement’ does not exist in the namespace ‘Microsoft’ (are you missing an assembly reference?)"

  7. Denis Orlov says:

    I could create a new Subscription!!!

    Thanks!

  8. Denis Orlov says:

    The first results

    (It is my first operational experience with C# and VS)

    First of all I can’t see new Notification channel.

    How to remove already created channels (by this code)?

    I want to add new subscription to the concrete monitor (alerts from only one monitor) and I don’t see how I can do this by this code.

    Where I can get all parameters, if I must use “Criteria” property of AlertChangedSubscriptionConfiguration Class for this? And I do not know where I can get Monitor ID.

    Thanks!

  9. JakubOleksy says:

    1. To find the notification channel, go to the Administration pane -> Settings -> Notification.

    2. You can delete from there, or programatically using the ManagementGroup.DeleteNotificationAction()/DeleteNotificationEndpoint() methods.

    3/4. You need to use criteria for this. Essentially, you can use any property that is defined on the MonitoringAlert object. For a monitor it is ProblemId.

  10. Denis Orlov says:

    Thanks Jakub!

    1. I can find there only channels which have been created through UI, and not one channel  through  this code.

    2. Thanks for advice

    3. I’ll try.

    Thanks a lot!

  11. JakubOleksy says:

    1. Looks like the UI uses specific names for the channels it shows:

    SmtpEndpoint and DefaultSmtpAction

    ImEndpoint and DefaultImAction

    SmsEndpoint and DefaultSmsAction

  12. Rico_Chang says:

    Hi Jakub,

    I have tested your sample code to create a subscription for our customer’s requirement for a while. However I could not find the code to control "Alert Aging" option in your sample code and SDK. Could you tell me how to control alert aging option under subscription? Thank you for your help.

  13. JakubOleksy says:

    Are you looking for alerts that haven’t changed in some time? For that, you should use AlertNotChangedSubscriptionConfiguration and the IdleMinutes property.

  14. Rico_Chang says:

    Thanks Jakub. That is what I need. Now I can understand the sdk descirption of IdleMinutes "Gets or sets the interval of time, in minutes, that alerts do not change.".

    I also find out you have sample code which used this property in another post.

    http://blogs.msdn.com/jakuboleksy/archive/2006/11/21/differences-between-mcf-in-mom-2005-and-scom-2007.aspx

    BTW, will MS plan to release a enhanced SCOM console that support creating complex subscription? I got exception window each time when I double-click subscription created by coding. It’s a little hard to maintain.

  15. JakubOleksy says:

    Unfortunately, there is no current plan to expand the UI support for creating subscriptions.

  16. JakubOleksy says:

    It would actually be helpful if you submitted feedback requesting this functionality as the largest reason for not doing it is not having a lot of feedback that it is necessary (and thus it gets prioritized below other issues). Here’s the site for feedback:

    http://connect.microsoft.com/site/sitehome.aspx?SiteID=209

  17. In MOM 2005 it was easy to notify someone on specific alerts. SCOM 2007 – with it&#39;s subscription

  18. 1. Is it possible to create notifications on a rule by rule basis? If so, how? If not, why not? Yes,

  19. jdpickering says:

    I’ve looked over your code above and I understand everything till you get down to the Alert Configuration.  Where do I get that?  I have a rule that I created and i want it to send out an Email when that alert is generated and I follow the creating the endpoint and everything but don’t understand where do i point it to my rule to say send email?

  20. JakubOleksy says:

    The send email part is the actions. For picking a particular rule, you need to change the xml configuration. If you look at the linked powershell example, that has another example of configuration for generating an email off a particular monitor. Check out that post and related comments and see if that clears things up.

  21. andydominey says:

    Hey Jakub,

    I need to be able to subscribe to a single alert in OpsMgr for a product connector here at the client site I am working on. I know this is possible for e-mail alerts as you have demonstrated. Is it possible to do the same for a connector subscription?

    Andy

  22. vsefcik says:

    Subscriptions that I add with this code all have a Last Modified Date in the e-mail body that is in UTC and not localized.  However, if I edit the e-mail format in the Operations Console and save it, the Last Modified Date is then localized.  Is there a property that needs to be set to have the Last Modified Date localized?  There is a TimeZone property in the AlertSubscriptionConfiguration object, but either I don’t know the format of the string or it is being ignored.

  23. JakubOleksy says:

    I am not 100% sure what the timezone format is, but if you export the Notifications.Internal.Library from the console you can see what the value is set to in the xml and set it to the same thing in code.

  24. vsefcik says:

    Many thanks for the lead, Jakub.  Your suggestion worked.  In case anyone else is interested, the TimeZone value for my area (Pacific coast) was:

    E001000000000000C4FFFFFF00000B0000000100020000000000000000000300000002000200000000000000|Pacific Standard Time

  25. StefanKoell says:

    Hi!

    I realize that you are now in another team, but maybe you can give us more insight on how to implement your solution to work with rules instead of monitors. Somehow this subscription only works with alerts generated by monitors. Any thoughts?

    Thanks

    cheers

    Stefan

  26. JakubOleksy says:

    If you use ProblemId in your configuration, that should be the MonitorId when the alert is generated from a monitor. Is that not working?

  27. Richard K says:

    The problem is that with Rules, the ProblemID isn’t the same each time an Alert is generated.  I’ve been attempting to use the MonitoringRuleId instead, but haven’t had much luck so far.

  28. JakubOleksy says:

    Yeah, you want to use MonitoringRuleId for rules and ProblemId for monitors.

  29. TheBowMan says:

    Hello!

    I want to create a Connector that takes new alerts generated by specific

    computers  and export them in an external applications.

    In order to filter the alerts I create a subscription but I am facing two

    problems:

    1st: I know that the only possible fields that I can apply the subscription

    on are the dbo.Alert fields of OperationsManager SQL DB. Here I cannot find a

    field containg the Computer name (nor the FQDN) that generates the alert.

    Therefore I thought to check for the hostname in the Alert Context field.

    2nd: the Alert Context field does not contain only the hostname but many

    field, therefore I decided to use "Like" as operator and the hostname as

    value. Ufortunately the "Like" operator does not work.

    I tried the enclosed subscriptions in order to understand how they works but

    I can only have working the subscriptions with "Equal" as operator.

    – Equal works.

    – Like (AlertName) should send to connector every alert generated by

    alertname with "core" occurrences instead nothing is passed. This is

    extremely odd because with equal I see the specific alerts. With Like

    (AlertName) I should see at least the alerts filtered by equal,

    instead…nothing.

    – Like (AlertContext) I thought to see all alerts coming from MASTERDC,

    instead: nothing.

    I actually made another try putting the value with the "Like" operator

    between two ( ‘ ) but still notihng

    Where did I made wrong? Could you supply me the correct subscription synthax ?

    Moreover: do you think that the solution I found (look for hostname in the

    alert context) is good or you suggest to look in someother place ?

    If yes, could give me some snippet?

    Thank you!

    Federico

    [equal]

    <SimpleExpression>

     <ValueExpression>

       <Property>AlertName</Property>

     </ValueExpression>

     <Operator>Euqal</Operator>

     <ValueExpression>

       <Value>SIMATIC IT 6.3 SP2 – Core – Program Registration Server –

    6002</Value>

     </ValueExpression>

    </SimpleExpression>

    [Like (AlertName)]

    <SimpleExpression>

     <ValueExpression>

       <Property>AlertName</Property>

     </ValueExpression>

     <Operator>Like</Operator>

     <ValueExpression>

       <Value>Core</Value>

     </ValueExpression>

    </SimpleExpression>

    [Like (AlertContext)]

    <SimpleExpression>

     <ValueExpression>

       <Property>Context</Property>

     </ValueExpression>

     <Operator>Like</Operator>

     <ValueExpression>

       <Value>MASTERDC</Value>

     </ValueExpression>

    </SimpleExpression>

  30. kramersteve says:

    What do you do with this script? Where is it loaded into SCOM?

  31. JakubOleksy says:

    The script in the post? You need to compile and run the code.

  32. JakubOleksy says:

    About the post on Dec 1st, sorry, I never received a notification about it. For your issue, you’d want to look at the filtering the subscriptions by group and/or type, outside of criteria. This is supported in the UI and you should be able to create the subscrption you want.

  33. kramersteve says:

    Sorry, I probably didnt word that correctly. I see the script and I can copy and paste that into a .ps1 file. Do you have a link to the process to compile and use it in the tool? I am very new to this tool and I havent been through this before.

  34. JakubOleksy says:

    Which script? The code in my post is C# and needs to be compiled.

  35. Elizabeth1978 says:

    Hello all!

    I want to create a subscription that forwards to my connector (created via SCOM SDK) the alerts coming from a custom computer group I created and called "MyGroup".

    In order to achieve this goal I completed these steps:

    1) I created the connector via SDK

    2) I created manually the subscription via the SCOM UI selecting only "MyGroup", the first option of Targets and checking all the checkboxes in the criteria

    3) I exported in a XML file via SCOM SDK the subscription just created

    …then I read the XML file and I noticed that it contains the criteria but does not mention any Computer Group (nor "MyGroup").

    Now I need to understand how PROGRAMMATICALLY associate a specific subscription to a specific computer group.

    Can some gentleman help me?

    Thank you!

    Bye

    Lizzy

  36. JakubOleksy says:

    If you look at the sample in this post, the AlertNotChangedSubscriptionConfiguration has a MonitoringObjectGroupIds that you would add the Id of your group to.

  37. Elizabeth1978 says:

    Hi Jakubm and thank’s for the support!

    Actually in your post I did not find mention about "MonitoringObjectGroupIds".

    I tried anyway to set the GUID of the Computer Group I created in this way:

    config.Criteria = XML_File_With_Criteria;

    Guid ComputerGroupGuid = new Guid("c8635b06-fbb1-cf1a-d019-38851f0505c0");

    config.MonitoringObjectGroupIds[0] = ComputerGroupGuid;

    The I compiled (no errors at all) and launched.

    The result is that the connector is created but the subscription creation is stopped (it seems paused) in le line of "config.MonitoringObjectGroupIds[0]".

    I put I try…catch but no errors are raised.

    Where I make wrong ?

    Thank you again!

    Elizabeth

  38. JakubOleksy says:

    You need:

    config.MonitoringObjectGroupIds.Add(ComputerGroupGuid);

  39. Elizabeth1978 says:

    Work greatly!

    Thank you!

    Huges and kisses!

    Lizzy!

  40. astra194 says:

    Yet again, your blog postings are hugely useful to me in attempting to access SCOM features programmatically, as the MSDN documentation is frequently rather terse, so many thanks.

    You note:

     In terms of which columns you can query for in the criteria, it is anything that is defined on the Alert table in the db.

    That’s great; I can see the table so I have the column names. But is there a definitive place I can get the column values? For example, Severity is, I think, Info=0, Warning=1, Critical=2, or is it?

    The SDK Glossary says:

     alert severity

       The property of an alert that indicates its seriousness; for example, Service Unavailable, Security Issue, Critical Error, Error, Warning, Information, and Success.

    so are there more values out there? And what about Priority and ResolutionState? I’m guessing all these are documented somewhere, and normally a good Googling finds them eventually, but not this time, at least, not without a few conflicting hits.

  41. JakubOleksy says:

    For both you can look at the enums as defined in the MonitoringAlert class. The values of the enums are the possible values. Resolution state is also extensible. Check out the MonitoringAlertResolutioState class.

  42. jchuck5612 says:

    This is fantastic stuff Jakub!

    Could you point me in the right direction on how to get a list of Notification Subscriptions based on a particular alert? I do not know how to tie a collection of NotificationSubscription objects together with objects returned in a MonitoringAlert collection.

    Any help would be greatly appreciated.

  43. JakubOleksy says:

    I am not sure I understand the question. What relationship are you trying to understand?

  44. Student says:

    Can you please let me know what are the prerequisites required before setting the alert notification?