In today’s world of monitoring it is not always easy for people from the service desk or even for administrators to identify from which system is this alert being sent, who is responsible for the system and maybe in a multitenant environment to which company belongs this system/alert.
In my case a company which is hosting Active Directory domains and systems for different companys (customers) wanted to have company, server and contact information displayed on the alert notification. E.g. if server1.contoso.com is having a problem, the service desk must be able to identify to which company this server belongs and who they might need to contact.
To keep things as easy as possible I wrote a script which dumps the information into the custom fields of the alert and also sends a mail containing all the needed information.
Steve Rachui has written a blog post about updating custom fields using subscriptions in SCOM 2007 R2.
Based on this I wanted to extend his approach to fit all my needs for SCOM 2012.
What’s going on
First I need a data source where I dump all the information about which server belongs to which company and who is the manager or contact. I decided to use a text file . It looks like this….
If an alert is being generated my script will be triggered and the information is dumped into the custom field1-3 and also into the mail footer.
Here I stopped the DNS Service on host kwsp1…
Alert properties…
…and the custom field information. Nice …
But look at my mail….isn’t it just cool?
If you think about it. You can add any additional information to an alert AND mail. This could be detailed company addresses, SLA information, 3rd level administrator information…whatever….
Setup
Create a text file company.txt and dump it on your management server’s c:\scripts folder. Enter all information you need according to this format. Add as many lines you need but make sure every server appears only once!
The next thing I set up a command channel according to Steve Rachui to execute my script. It goes like this….
1: c:\windows\system32\windowspowershell\v1.0\powershell.exe
2: -Command "& '"C:\scripts\AlertUpdateV10.ps1"'" '$Data/Context/DataItem/AlertId$'
3: c:\windows\system32\windowspowershell\v1.0\
Next you need to set up the subscriber and the subscription. The subscription there you will define when the command will be triggered. In my case I selected all critical alerts…
…and my administrator as subscriber,
Of course as a last step the command channel…
Save this script on your management server e.g. in c:\scripts as AlertUpdateV10.ps1. This script needs the alert id as parameter.
- Param(
- [parameter(mandatory=$true)][GUID] $alertid
- )
- #Define path to the file containing the information. The header structure is server;company;manager. Append data separated by “;”.
- #e.g. the file looks like this
- #
- #server;company;manager
- #server1.domain.local;microsoft;Bill Gates
- #server99.domain.local;itnetx;Stefan Roth
- $infofile=“c:\scripts\company.txt”;
- #Import the file
- $infos=Import-Csv -delimiter “;” $infofile | Select server,company,manager;
- #Check if the OperationsManager module is loaded
- $checksnap = Get-Module | Where-Object {$_.name -eq “OperationsManager”};
- if ($checksnap.name -ne “OperationsManager”)
- {
- Import-Module OperationsManager;
- }
- #Convert the alert ID and get the alert
- $alertid = $alertid.toString();
- $newalert = Get-SCOMAlert -Criteria “Id = ‘$alertid'”;
- #Get the alert source server
- $server= $newalert.principalname;
- #Check if the alert has information about the server where the problem occured.
- If (!$server){$server=“N/A”};
- #Check if the customfield1 contains data, if not the alert has not been modified yet.
- If (!$newalert.customfield1) {
- #Get the server name, company and manager information from the file and add it into the customfields
- foreach ($info in $infos) {
- If ($server.tolower() -match $info.server.tolower()) { $newalert.customfield1 =$info.server; $newalert.customfield2 =$info.company;$newalert.customfield3 = $info.manager;$newalert.Update(“”);}
- }
- If (!$newalert.customfield2){$newalert.customField2 =“No customer information available”};
- }
- #Configure mail settings
- #############################################
- $to=“administrator@contoso.local”;
- $from=“SCOM@contoso.local”;
- $smtpserver=“exchange.contoso.local”;
- $webconsoleserver=“webconsoleserver.contoso.local”;
- #############################################
- #Map alert data to variables which will be used in the mail body
- $alertname=$newalert.name;
- $lastmodifiedby=$newalert.lastmodifiedby;
- $lastmodified=$newalert.lastmodified;
- $alertdescription=$newalert.description;
- $alertpath=$newalert.monitoringobjectpath;
- $alertsource=$newalert.monitoringobjectdisplayname;
- $customfield1=$newalert.customfield1;
- $customfield2=$newalert.customfield2;
- $customfield3=$newalert.customfield3;
- $alerturl=“http://”+$webconsoleserver+“/OperationsManager?DisplayMode=Pivot&AlertID=”+“{“ + $newalert.id + “}”;
- #Get alert resolutionstate
- switch ($newalert.resolutionstate)
- {
- 0 {$alertresolutionstate=“New”};
- 255 {$alertresolutionstate=“Closed”};
- }
- #Define the body of the mail
- ############################################
- $body=@”
- Alert: $alertname
- Source: $alertsource
- Path: $alertpath
- Last Modified By: $lastmodifiedby
- Last Modified Date: $lastmodified
- Alert Description: $alertdescription
- URL: $alerturl
- This alert belongs to the customer:
- =======================================
- Server: $customfield1
- Company: $customfield2
- Contact: $customfield3
- “@
- ############################################
- #Build the subject line
- $subject=$alertname + ” – “ + “Severity: “ + $newalert.severity + ” / “ + $alertresolutionstate;
- #Send mail
- Send-MailMessage -To $to -From $from -Subject $subject -SmtpServer $smtpserver -Body $body;
Skydrive Download
There is now only one problem. The Management Server Action Account will execute this script. And because of that I added the MSAA to the local Administrators group on the management server.
In addition I needed to set up a special permission on my Exchange Server 2010 to allow this account to send mail. If you don’t set this permission you will likely get an error “The server response was: 5.7.1 Client does not have permissions to send as this sender”.
I had to get the name of the receive connector in my case “Default EXC01”.
Then I executed this command in the Exchange Management Shell to set the permission…
add-adpermission “Default Exc01” -User “Domain\MSAA Acount” -ExtendedRights ms-Exch-SMTP-Accept-Authoritative-Domain-Sender
I am not using this approach in production yet. I am not sure how the performance will be if there are 500 and more monitored systems. I thought it is a great idea so i built it .
Keep on scomming….
Thank you soo much! I was going in circles tinyrg to get this up and running correctly until I found this very nice walk-through.I did want to add a note that for SQL Server 2008 R2. In order to install OpsMgr, you have to use the DBCreatorWizard.exe under the folder Support Tools on the Operations Manager Install CD. Otherwise, the installation wizard fails to detect your database and will not continue.
Will this process work for the following I’m trying to create:
server;Store
12.345.67.89.domain.com;01234
Hi Teresa
You can use whatever data you want, as long a you separate them by a delimiter “;”.
Cheers,
Stefan
Thanks Stefan I’m using the delimiter but it is not working for IP address could this statement be wrong and would I put this expression before $infofile or after?
Statement is here:
#”12.345.67.89″.xyzcompany.com;8121 -match “d{1,3}.d{1,3}.d{1,3}.d{1,3}” (True)
$infofile=”C:ScriptsIPAddress.txt”;
Nice one! Thank you for sharing.
Hi Stefan, I’m using the “;” delimter however the custom fields are getting updated, can you please provide some insight.
Thanks
Sorry meant to say the custom fields in my Alerts are not getting updated. Thanks
Hi Teresa,
If you use $newalert.update() in the script it may help updating / refreshing the alert.
Cheers,
Stefan
Thanks Stefan is there anyway I can send you my script, sorry brand new to powershell so not sure where to put line to refresh the alert.
Thanks
Thanks for the info. I wanted to know how were you able to get the Severity in the subject? I have been trying to change that and right now all I get is a 1 or 2 using the following:
Alert: $Data[Default=’Not Present’]/Context/DataItem/Severity$
Hi Stefan, I’ve just read this post as I’m trying to achieve a similar solution to updating Alert custom field details. Your post is very helpful, however I’m trying to implement slightly differently and wonder if what I’m trying to do is even possible as I lack the powershell knowledge to implement and wonder if you could advise if its possible and could your script be easily tweeked to accommodate.
What I’m trying to do differently is basically instead of building a local text file on the mgmt server to hold all the custom field data, I was hoping to be able to interrogate a file that is already present locally on each agent machine which already has the custom detail I need to pull out – something like BGInfo data on each server. Could the script run to interrogate the file local on each agent based on alet source principle name instead of querying the txt file on the management server – I have over 600 agents and manually building the txt file isnt straigh forward as I won’t know all the correct ‘owner’ details which are already available on the local agent bginfo file.
Any advice much appreciated!!…
Hi
Well this PowerShell way of doing alert update existed before Microsoft release the Alert Update Connector http://blogs.technet.com/b/kevinholman/archive/2012/09/29/opsmgr-public-release-of-the-alert-update-connector.aspx .
If I were you I would have look first at this connector, if it fits your needs.
Cheers,
Stefan
Hi Stefan,
yes I’ve acutally got Orchestrator in our environment and have got a runbook set up now seems to be doing the job, just need a bit more testing befor making it production though!. Thanks for the reply…
Hi Stefan
Excellent article, thanks for that. I have got a question which I can’t find an answer to.
I have got a script(I didn’t write it), which looks at the names of certain alerts and then changes it on SCOM 2012. I have created the it looks like the following:
param ($rootMS)
$rootMS=”
#Initializing the Ops Mgr 2007 Powershell provider
add-pssnapin “Microsoft.EnterpriseManagement.OperationsManager.Client” -ErrorVariable errSnapin ;
set-location “OperationsManagerMonitoring::” -ErrorVariable errSnapin ;
new-managementGroupConnection -ConnectionString:$rootMS -ErrorVariable errSnapin ;
set-location $rootMS -ErrorVariable errSnapin ;
$Alerts = get-alert -criteria ‘Name = ”IIS 7 Web Site is unavailable”’ | Where {$_.ResolutionState -eq 0}
foreach($Alert in $Alerts)
{$Alert.ResolutionState = 20
$Alert.Update(“Resolution State Changed”)}
It works when I run it from the powershell window but doesn’t seem to work from the command channel i.e, the alerts get changed when I run it manually it works and the . My command channel looks like this:
Full path of the command line:
c:windowssystem32WindowsPowerShellv1.0powershell.exe
Command line parameters:
“C:TempChangeResState_IIS.ps1” ‘$Data/Context/DataItem/AlertId$’
Startup folder for the command line:
c:windowssystem32windowspowershellv1.0
I have also tried C:TempChangeResState_IIS.ps1 and C:Temp as the Command line parameters:and Startup folder for the command line:without any luck.
I think the command line parameter might be wrong. Also should the startup folder be what it is or should that be changed. I am new to SCOM and powershell, please help?
Thanks in advance.
Regards,
Hi
Thank you!
Make sure you set the notification channel as on this picture http://scomfaq.files.wordpress.com/2012/04/image65.png It does not seem the case…
Cheers,
Stefan
Hi
I also forgot to mention that I have already created custom resolution state from the SCOM 2012 console.
Thanks again.
Regards
Hi
Can you please tell me how did you get the severity in the email as “error” instead of numerical values like 1, 2 etc. From the console if i select severity parameter it shows only numerical value int he alert email.
Stefan:
Thanks for the awesome article. I’m trying out this setup, and can’t quite make it work. I have the script in place and configured the subscription and command channel as in your article. But I have more than one RMS server. I copied the script and text file to the same place on all of my RMS servers (D: drive). I also stopped short in your script where it generates email (line 47). Still no luck. Anything else I should be looking for?
I had the same issue and found through some testing that the powershell cmdlets were not being loaded into powershell when the script was triggered. Due to this, the powershell command did not recognize ‘Get-SCOMAlert’ . I added the line Import-Module -Name OperationsManager to the beginning of the script and it now works. The issue I am running into now is that it updates the alert every minute and I am concerned that this is going to cause a lot of churn on the server when I start adding more severs into the text file.
Thanks for the post. I think I am on track now. but my required result is a little bit different.
I need to input the info into the customfield, which can be done using the above method, then forward the whole alert as SNMP Trap to another system. I planned to use Trapgen.exe
Do you think this is possible?
Hi
Well yeah it should be possible, but not a very sexy way. A more reliable and advanced way would be using Orchestrator using the Get Alert activity in conjunction with Send SNMP Trap http://technet.microsoft.com/en-us/library/hh206050.aspx activity would solve your problem.
Cheers,
Stefan
Thanks for your quick reply and this page really save me a lot of time.
Good day! Stefan, can you help me? It script working, when it manually run, but in auto mode I got some issue. I wanted look for problem and I added write log, for example
autorun script following:
N/A
6c2c996f-768e-4d2b-af7a-d512e2f88b20
manually run:
6c2c996f-768e-4d2b-af7a-d512e2f88b20
ConfigMgr Server Component Issue
VUZS-SVE-SM-001.life.corp
managmentpoint (from text file information)
Help me, please! Thanks
Regards
Thanks for the great post. Have you been able to test this in a production environment yet and if so, how does SCOM handle it? Is this still the way to go?
Hi Stefan Roth,
In command channel which admin account need to Give local or domain Admin
How about this one below from
$MS=”Servername”
if ((Get-PSSnapin | Where-Object {$_.Name -eq ‘Microsoft.EnterpriseManagement.OperationsManager.Client’}) -eq $null)
{
Add-PSSnapin Microsoft.EnterpriseManagement.OperationsManager.Client -ErrorAction SilentlyContinue -ErrorVariable Err
if ($Err)
{
$(throw write-Host $Err)
}
}
if ((Get-ManagementGroupConnection | Where-Object {$_.ManagementServerName -eq $MS}) -eq $null)
{
New-ManagementGroupConnection $MS -ErrorAction SilentlyContinue -ErrorVariable Err
if ($Err)
{
$(throw write-Host $Err)
}
}
if ((Get-PSDrive | Where-Object {$_.Name -eq ‘Monitoring’}) -eq $null)
{
New-PSDrive -Name: Monitoring -PSProvider: OperationsManagerMonitoring -Root: \ -ErrorAction SilentlyContinue -ErrorVariable Err
if ($Err)
{
$(throw write-Host $Err)
}
}
Set-Location Monitoring:\$MS
#Get-Alert – update alert
foreach ($alert in get-alert -criteria ‘ResolutionState = 0’)
{
$alert.CustomField1 = $alert.PrincipalName
if (($alert.CustomField1 -eq ”) -or ($alert.CustomField1 -eq $null) )
{
$systemname = $alert.MonitoringObjectFullName
$alert.CustomField1 = $systemname.split(“:;”) |select -Index 1
}
$alert.CustomField2 = $alert.Severity
$alert.ResolutionState = “5”
if ($alert.IsMonitorAlert -like ‘False’)
{
$alert.CustomField3 = ((get-rule $alert.monitoringruleid).getmanagementpack()).displayname
}
else
{
$alert.CustomField3 = (get-monitor $alert.problemid).getmanagementpack().displayname
}
$alert.Update(“Filling the CustomFields”)
}
Hi,
May I know what are the changes needed to the script if I only want the custom field to be updated in SCOM alert and do not want sending of email?
Thank you.