in

code4ward

code4ward.net

information technologies | consulting | development

Set-NotificationForAlert

In MOM 2005 it was easy to notify someone on specific alerts. SCOM 2007 - with it's subscription based system - cannot handle these kind of notifications. But the limitation is the user interface. Jakub from the SCOM 2007 product team released some very useful code which helped to implement a notification based on the alert name. One problem of Jakubs code is, that it's a C# program which is not very handy and that he creates most of the stuff in code which can be created with the UI.

I translated the script to power shell, which should be much friendlier to use, deploy and let's you quickly tweak some settings. The code below works for me (at least working with email notifications), but I have to admit, I didn't test it that much. The script usage is pretty simple, but you have to do some stuff first:

  • Setup email notification
  • Create at least one recipient
  • The alert has to be raised at least once
  • Change the $RMS variable in the script to your root management server

Then, just execute it in Power Shell: ".C:\Set-NotificationForAlert.ps1 "This is a test alert" "This is a test notification recipient"

Parameter 1: The name of the alert

Parameter 2: The name of the recipient

## check for parameters
param(
[string]$AlertName = $(throw write-host "You did not specify the -AlertName parameter."),
[string]$NotificationRecipientName = $(throw write-host "You did not specify the -NotificationRecipientName parameter. Use the Get-NotificationRecipient command to get a list of all registered notification recipients")
)
 
$RMS = "RootManagementServerName"
 

write-Host
write-Host "Executing Set-NotificationForAlert.ps1 ..."
write-Host

## prepare OpsMgr shell

if ((Get-PSSnapin | Where-Object {$_.Name -eq 'Microsoft.EnterpriseManagement.OperationsManager.Client'}) -eq $null) {
Write-Host
Write-Host "File OpsMgrV3.ps1 loaded."
Write-Host "Initializing shell for operations manager..."
Write-Host "Add Microsoft.EnterpriseManagement.OperationsManager.Client snap in."
Add-PSSnapin Microsoft.EnterpriseManagement.OperationsManager.Client -ErrorAction SilentlyContinue -ErrorVariable Err
if ($Err) { $(throw write-Host $Err) }
}

if ((Get-ManagementGroupConnection | Where-Object {$_.ManagementServerName -eq $RMS}) -eq $null) {
Write-Host "Connect to Management Server: $RMS"
New-ManagementGroupConnection $RMS -ErrorAction SilentlyContinue -ErrorVariable Err
if ($Err) { $(throw write-Host $Err) }
}

if ((Get-PSDrive | Where-Object {$_.Name -eq 'Monitoring'}) -eq $null) {
Write-Host "Create Monitoring drive from Provider."
New-PSDrive -Name: Monitoring -PSProvider: OperationsManagerMonitoring -Root: \ -ErrorAction SilentlyContinue -ErrorVariable Err
if ($Err) { $(throw write-Host $Err) }
Write-Host "Operations manager shell initialized."
Write-Host
}

Set-Location Monitoring:\$RMS

$Alerts = Get-Alert | where {$_.Name -eq $AlertName}
if ($Alerts.ProblemId -eq $null)
{
if ($Alerts.Count -gt 0)
{
$ProblemID = $Alerts[0].ProblemId.ToString()
}
else
{
throw write-host "No alert was found with the specified name"
}
}
else
{
$ProblemId = $Alerts.ProblemId.ToString()
}


## load SDK assemblies
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.EnterpriseManagement")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.EnterpriseManagement.Configuration")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.EnterpriseManagement.ConnectorFramework")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.EnterpriseManagement.Monitoring")

## connect to management group
$ManagementGroup = New-Object Microsoft.EnterpriseManagement.ManagementGroup($RMS)
$ManagementGroup.Reconnect()

$smtpAction = $ManagementGroup.GetNotificationAction("DefaultSmtpAction")
$recipient = $ManagementGroup.GetNotificationRecipient($NotificationRecipientName)
$config          = New-Object Microsoft.EnterpriseManagement.Administration.AlertChangedSubscriptionConfiguration([Microsoft.EnterpriseManagement.Administration.AlertSubscriptionConfigurationType]::Any)

$config.Criteria = "<SimpleExpression><ValueExpression><Property>ProblemId</Property></ValueExpression><Operator>Equal</Operator><ValueExpression><Value>$ProblemId</Value></ValueExpression></SimpleExpression>"

$config.ExpirationStartTime = Get-Date
$config.PollingIntervalMinutes = 1

$NewGuid = [System.Guid]::NewGuid()
$NewGuid = $NewGuid.ToString().Replace('-', '_')

$Subscription = New-Object Microsoft.EnterpriseManagement.Administration.AlertNotificationSubscription("STACustomSubscription$NewGuid", $config)

$Subscription.DisplayName = $NotificationRecipientName + " - " + $AlertName
$Subscription.ToRecipients.Add($recipient)
$Subscription.Actions.Add($smtpAction)
$ManagementGroup.InsertNotificationSubscription($Subscription)

 

So, hopefully I can ease some pain with this...

Comments

 

» Set-NotificationForAlert said:

Pingback from  &raquo; Set-NotificationForAlert

September 19, 2007 9:35
 

Jakub@Work : Notification Subscriptions said:

Pingback from  Jakub@Work : Notification Subscriptions

September 26, 2007 6:26
 

Geist23 said:

How do you make it stop notification? set the recipient to null? ""

Additionally, I have an rule that looks for an event and then reports a critical Alert. I have generated this 10 of these alerts and when I run the script it says it cannot find the Alert name. I can send an outline with screen shots of the steps I take.

Oktober 16, 2007 11:00
 

StefanKoell said:

Stop the notification is simple. The script creates a subscription, which you can see in the GUI. You cannot edit the subscription, because the criteria expression is not supported in the GUI but you can delete the subscription. To get the script up and running the alert with the name specified has to be raised at least once.

Oktober 16, 2007 11:10
 

Geist23 said:

I decided to look at this a little deeper:

I saw that you used the get-alert and did a hash table to filter out by the Name. So I decided to check the filter myself in Powershell:

$AlertName = "Enterprise Faxing Rule"

Get-Alert | where {$_.Name -eq $AlertName}

Excellent! It returns the Alerts raised by my NT Event Log rule.

then I try:

powershell -noexit "c:\scripts\SetNotificationForAlert.ps1" "Enterprise Faxing Rule" "David"

And I get the following error:

No alert was found with the specified name

ScriptHalted

At C:\scripts\SetNotificationForAlert.ps1:49 char:8

+         throw  <<<< write-host "No alert was found with the specified name"

No Alert was found, but I found it! Hmmm....

Oktober 16, 2007 11:48
 

Geist23 said:

As i manually type out the script and test each line I can see where the problem comes into play

$Alerts.ProblemId -eq $null

True

Your scripts checks for this condition of null.

The bigger question is why am I getting null?

$Alerts does return many entries with a proper problemID filled out.

Oktober 17, 2007 12:06
 

Geist23 said:

Here is an example of what I return:

Id                                : 1bb0434c-1079-4dab-8f70-f08456f16ea4

Name                              : Enterprise Faxing Rule

Description                       : Please check Enterprise Faxing on Miwimx20

MonitoringObjectId                : 07dcaab9-2b7d-7c8e-5832-423dfad99cf2

MonitoringClassId                 : ea99500d-8d52-fc52-b5a5-10dcd1e9d2bd

MonitoringObjectDisplayName       : miwimx20.corp.tds.local

MonitoringObjectName              : miwimx20.corp.tds.local

MonitoringObjectPath              :

MonitoringObjectFullName          : Microsoft.Windows.Computer:miwimx20.corp.tds.

                                   local

IsMonitorAlert                    : False

ProblemId                         : 606bbe38-d726-4780-8713-f4e83f631e29

MonitoringRuleId                  : 884768e7-bacb-5090-f33b-6f510184bdd4

ResolutionState                   : 255

Priority                          : High

Severity                          : Error

Category                          : Custom

Owner                             :

ResolvedBy                        : CORP\admrns

TimeRaised                        : 10/15/2007 7:50:20 PM

TimeAdded                         : 10/15/2007 7:50:29 PM

LastModified                      : 10/15/2007 7:54:01 PM

LastModifiedBy                    : CORP\admrns

TimeResolved                      : 10/15/2007 7:54:01 PM

TimeResolutionStateLastModified   : 10/15/2007 7:54:01 PM

Oktober 17, 2007 12:17
 

Geist23 said:

I finally got the subscription to generate based on the rule I created "Enterprise Faxing Rule"

Instead of running the script like this:

powershell -noexit "c:\scripts\SetNotificationForAlert.ps1" "Enterprise Faxing Rule" "David Clapp"

I open up the SCOM shell and then enter in:

c:\scripts\SetNotificationForAlert.ps1 "Enterprise Faxing Rule" "David"

The subscription is created and I can see it in the UI and it is enabled.

Now if only it would send me an email....

Oktober 17, 2007 9:18
 

StefanKoell said:

Funny, that's happening to me too all the time. It seems that the rule needs some time to get up and running. I always disable and re-enable the rule using the GUI and after 20 or 30 minutes I get mails... Maybe you are experiencing the same thing.

Are other subscription (created by UI) using the same recipient working?

Oktober 17, 2007 9:26
 

Geist23 said:

Yup. You are right. I just had to wait it out. Which is scary because I am running a 4-way 64bit w/Win2k3 Enterprise 64bit, SQL2005 64bit on box, and RAID 10 with aprox 10 spindles.

thanks for letting me vent here as I worked with your script.

It does really matter how the script is executed . Via Start>Run = Problems

From SCOM 2007 Command Shell = Great

One final thing. The script was really hard to copy and paste from your table box because all the line breaks were dropped out.  Anyway you could offer it as a link to download or preserve the line breaks somehow...etc.

Oktober 17, 2007 10:20
 

StefanKoell said:

thanks for the feedback, and glad it worked for you. I will provide a text file and link it in the blog...

Oktober 17, 2007 10:34
 

Geist23 said:

Well, after letting the subscription run over night I came into work this morning and realized it was sending EVERY alert not just the ones named "Enterprise Faxing Rule"

Oktober 18, 2007 6:03
 

peterk said:

i get stuck with the script. It keeps giving me this error ...  any ideas ?

Exception calling "InsertNotificationSubscription" with "1" argument(s): "The notification subscription was invalid for insert. See inner exception for details."

At \temp\Set-NotificationforAlert.ps1:88 char:48

+ $ManagementGroup.InsertNotificationSubscription( <<<< $Subscription)

November 13, 2007 2:18
 

Megan Kielman said:

I am having the same problem as Geist23 where the notification subscription is created but I am getting notifications for more then just the alert that I specified on the command line.

I looked through the script and the only piece that appears to configure the subscription were these lines of code:

$config          = New-Object Microsoft.EnterpriseManagement.Administration.AlertNotChangedSubscriptionConfiguration([Microsoft.EnterpriseManagement.Administration.AlertSubscriptionConfigurationType]::Any)

$config.Criteria = "<SimpleExpression><ValueExpression><Property>ProblemId</Property></ValueExpression><Operator>Equal</Operator><ValueExpression><Value>$ProblemId</Value></ValueExpression></SimpleExpression>"

$config.ExpirationStartTime = Get-Date

$config.PollingIntervalMinutes = 1

My first thought was that both monitors had the same ProblemID but that is not the case. Any thoughts on how to fix this so I only get notified on the alert I specified when running the script?

Megan

Jänner 8, 2008 5:20
 

StefanKoell said:

It seems, that the script doesn't work in every environment. I really don't see why. I used the script for some time now and in my environment it works really well - except for the delay until the rule is actually active.

As you could see in the post, the code was originally posted by a MS OpsMgr team member (blogs.msdn.com/.../notification-subscriptions.aspx) in C# and all I did, was to port it to power shell and to make it simpler to work with email subscription. As I cannot really repro your issues I really hope that someone who has problems in his environment can solve this and shed some light on this. I really would appreciate if this hero also posts his solution here because I am very interested to see what's still missing in the script ...

Jänner 9, 2008 9:35
 

StefanKoell said:

It seems, that someone else gave it a shot: blogs.technet.com/.../opsmgr-2007-creating-a-subscription-for-future-occurrences-of-an-alert.aspx

I didn't test it yet, but looks like a promising starting point...

Jänner 21, 2008 12:08
 

StefanKoell said:

Another update

I just followed some newsgroup discussion regarding the script and it seems that there was a typo in it:

change

$config          = New-Object

Microsoft.EnterpriseManagement.Administration.AlertNotChangedSubscriptionConfiguration([Microsoft.EnterpriseManagement.Administration.AlertSubscriptionConfigurationType]::Any)

to

$config          = New-Object

Microsoft.EnterpriseManagement.Administration.AlertChangedSubscriptionConfiguration([Microsoft.EnterpriseManagement.Administration.AlertSubscriptionConfigurationType]::Any)

Jänner 21, 2008 1:23
 

Steve Rachui's Manageability blog - SMS/MOM said:

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

Jänner 21, 2008 3:36
 

Andrzej's "IT Thoughts" Weblog said:

There is a couple of things about OpsMgr 2007 notifications, that may not be so obvious at first sight.

März 22, 2008 9:29
 

Kevin Holman's OpsMgr Blog said:

So.... Say I am an Exchange Administrator in a global company.... in the good old USA. My company has

Mai 4, 2008 7:48
 

RichardK said:

I had a problem where the LastModified date/time in the Subscription emails were in UTC instead of my local timezone.

You can set an additional config option in the script above.  My local time is Central Standard Time, so I exported the Notifications Internal Library MP and did a search for TimeZone in the resultant .xml file to get the correct value for my time zone.

Then just add the following to the above script right below the other 2 config options (substituting the value for your timezone):

$config.TimeZone = "6801000000000000C4FFFFFF00000B0000000100020000000000000000000300000002000200000000000000|Central Standard Time"

Juni 27, 2008 11:49
 

CarlosCaldas said:

It's working for me very well. One thing I want to do is to only receive new status I don't want to get e-mails when they close.

In order to copy and paste with line breaks I used Word to paste got all line breakes and then copy and pasted on notepad.

Juli 10, 2008 1:09
 

RicardoRodriguez said:

Hello there, I have noticed that the SCRIPT only works for monitor based alerts. Any alert comming from a monitor works because they use ProblemID as the MonitoringRuleID field. For all the cases the ProblemID would be the very same no matter the alert.

For rule based alerts it doesn't work like that. The ProblemID ain't the same in every alert so the script doesn't forward those.

Any clue about what the ProblemID points to when the alert is comming from a rule?

Juli 17, 2008 12:29
 

StefanKoell said:

Hallo Ricardo!

Thanks for sharing this knowledge. I must admit, that I never used my script with rule based alerts. Maybe I can find a way to get that to work with rule based alerts as well.

Juli 17, 2008 9:59
 

RicardoRodriguez said:

I'm currently working for doing so too. I require that functionality since I got some monitoring requirements which rely on non inventoried artifacts, so notification subscriptions cannot be done using the common UI subscriptions.

I would like to know what the ProblemID points to for the rule based alerts. If got any success I will let you know.

Greetings.

Juli 17, 2008 7:40
 

RichardK said:

could we just change:

$config.Criteria = "<SimpleExpression><ValueExpression><Property>ProblemId</Property></ValueExpression><Operator>Equal</Operator><ValueExpression><Value>$ProblemId</Value></ValueExpression></SimpleExpression>"

to:

$config.Criteria = "<SimpleExpression><ValueExpression><Property>MonitoringRuleID</Property></ValueExpression><Operator>Equal</Operator><ValueExpression><Value>$MonitoringRuleID</Value></ValueExpression></SimpleExpression>"

?

Juli 21, 2008 5:41
 

RichardK said:

ignore my post right above this one.  Here is how I was able to get it working with rules:

change:

if ($Alerts.ProblemId -eq $null)

{

   if ($Alerts.Count -gt 0)

   {

       $ProblemID = $Alerts[0].ProblemId.ToString()

   }

   else

   {

       throw write-host "No alert was found with the specified name"

   }

}

else

{

   $ProblemId = $Alerts.ProblemId.ToString()

}

to:

if ($Alerts.MonitoringRuleId -eq $null)

{

if ($Alerts.Count -gt 0)

{

$MonitoringRuleId = $Alerts[0].MonitoringRuleId.ToString()

}

else

{

throw write-host "No alert was found with the specified name"

}

}

else

{

$MonitoringRuleId = $Alerts.MonitoringRuleId.ToString()

}

then change:

$config.Criteria = "<SimpleExpression><ValueExpression><Property>ProblemId</Property></ValueExpression><Operator>Equal</Operator><ValueExpression><Value>$ProblemId</Value></ValueExpression></SimpleExpression>"

to:

$config.Criteria = "<SimpleExpression><ValueExpression><Property>RuleId</Property></ValueExpression><Operator>Equal</Operator><ValueExpression><Value>$MonitoringRuleId</Value></ValueExpression></SimpleExpression>"

Juli 21, 2008 10:24
 

RicardoRodriguez said:

Where did you find that you must be using the property "RuleId" than "MonitoringRuleId"?

If you use the real attribute name "MonitoringRuleId" you get errors at the RMS. How did you manage to know which property name the criteria field would accept?

Juli 24, 2008 3:04
 

RichardK said:

Criteria Properties can be any Property that exits in the Alerts table of the OperationsManager Database.  There is no column named "MonitoringRuleId" in the actual Alerts database table, but there is a column named RuleId and it has the same value as the MonitoringRuleId attribute.

From Jakub's intial post about this process:

"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"

blogs.msdn.com/.../notification-subscriptions.aspx

Juli 24, 2008 3:45
Copyright © by Stefan Koell | code4ward | All rights reserved
Disclaimer   Terms of Use   Privacy Statement  Imprint
Powered by Community Server (Non-Commercial Edition), by Telligent Systems