SCOM 2012 – Using Alert Custom Fields

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 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 Smiley. 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 Smiley


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….


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.

  1. Param(
  2. [parameter(mandatory=$true)][GUID] $alertid
  3. )
  4. #Define path to the file containing the information. The header structure is server;company;manager. Append data separated by “;”.
  5. #e.g. the file looks like this
  6. #
  7. #server;company;manager
  8. #server1.domain.local;microsoft;Bill Gates
  9. #server99.domain.local;itnetx;Stefan Roth
  10. $infofile=“c:\scripts\company.txt”;
  11. #Import the file
  12.   $infos=Import-Csv -delimiter “;” $infofile | Select server,company,manager;
  13. #Check if the OperationsManager module is loaded
  14. $checksnap = Get-Module | Where-Object {$ -eqOperationsManager”};
  15. if ($ -neOperationsManager”)
  16.     {
  17.         Import-Module OperationsManager;
  18.     }
  19. #Convert the alert ID and get the alert
  20. $alertid = $alertid.toString();
  21. $newalert = Get-SCOMAlert -Criteria “Id = ‘$alertid'”;
  22. #Get the alert source server
  23. $server= $newalert.principalname;
  24. #Check if the alert has information about the server where the problem occured.
  25. If (!$server){$server=“N/A”};
  26. #Check if the customfield1 contains data, if not the alert has not been modified yet.
  27.     If (!$newalert.customfield1) {
  28.         #Get the server name, company and manager information from the file and add it into the customfields
  29.         foreach ($info in $infos) {
  30.         If ($server.tolower() -match $info.server.tolower()) { $newalert.customfield1 =$info.server; $newalert.customfield2 =$;$newalert.customfield3 = $info.manager;$newalert.Update(“”);}
  31.             }
  32.         If (!$newalert.customfield2){$newalert.customField2 =“No customer information available”};
  33.         }
  34. #Configure mail settings
  35. #############################################
  36. $to=“administrator@contoso.local”;
  37. $from=“SCOM@contoso.local”;
  38. $smtpserver=“exchange.contoso.local”;
  39. $webconsoleserver=“webconsoleserver.contoso.local”;
  40. #############################################
  41. #Map alert data to variables which will be used in the mail body
  42. $alertname=$;
  43. $lastmodifiedby=$newalert.lastmodifiedby;
  44. $lastmodified=$newalert.lastmodified;
  45. $alertdescription=$newalert.description;
  46. $alertpath=$newalert.monitoringobjectpath;
  47. $alertsource=$newalert.monitoringobjectdisplayname;
  48. $customfield1=$newalert.customfield1;
  49. $customfield2=$newalert.customfield2;
  50. $customfield3=$newalert.customfield3;
  51. $alerturl=“http://”+$webconsoleserver+“/OperationsManager?DisplayMode=Pivot&AlertID=”+“{“ + $ + “}”;
  52. #Get alert resolutionstate
  53. switch ($newalert.resolutionstate)
  54. {
  55.         0 {$alertresolutionstate=“New”};
  56.         255 {$alertresolutionstate=“Closed”};
  57. }
  58. #Define the body of the mail
  59. ############################################
  60. $body=@”
  61. Alert: $alertname
  62. Source: $alertsource
  63. Path: $alertpath
  64. Last Modified By:   $lastmodifiedby
  65. Last Modified Date: $lastmodified
  66. Alert Description:  $alertdescription
  67. URL: $alerturl
  68. This alert belongs to the customer:
  69. =======================================
  70. Server:  $customfield1
  71. Company: $customfield2
  72. Contact: $customfield3
  73. “@
  74. ############################################
  75. #Build the subject line
  76. $subject=$alertname + ” – “ + “Severity: “ + $newalert.severity + ” / “ + $alertresolutionstate;
  77. #Send mail
  78. 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 Smiley.

Keep on scomming….

27 Replies to “SCOM 2012 – Using Alert Custom Fields

  1. 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.

  2. Will this process work for the following I’m trying to create:

      1. 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″;8121 -match “d{1,3}.d{1,3}.d{1,3}.d{1,3}” (True)

  3. Hi Stefan, I’m using the “;” delimter however the custom fields are getting updated, can you please provide some insight.


        1. 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.


  4. 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$

  5. 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!!…

      1. 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…

  6. 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)
    #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:
    Command line parameters:
    “C:TempChangeResState_IIS.ps1” ‘$Data/Context/DataItem/AlertId$’
    Startup folder for the command line:

    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.


  7. Hi

    I also forgot to mention that I have already created custom resolution state from the SCOM 2012 console.

    Thanks again.

  8. 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.

  9. 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?

    1. 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.

  10. 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?

  11. 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:
    manually run:
    ConfigMgr Server Component Issue
    managmentpoint (from text file information)

    Help me, please! Thanks

  12. 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?

  13. How about this one below from

    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
    $alert.CustomField3 = (get-monitor $alert.problemid).getmanagementpack().displayname
    $alert.Update(“Filling the CustomFields”)

  14. 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.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.