SCOM Enhanced Email Notification Script Version 2.1


In September of 2010 Tao Yang wrote a fantastic Powershell script (v2.0 here) for command channel notifications in System Center Operations Manager. Here is my adaptation of the script.

NOTE: I’ve tested this thoroughly in my lab and I suggest you do the same before using in any other environments. This script is meant to be an example and therefore use it at your own risk.

Download current version from Technet here: Download

Version History

  • Update! 2015.11.5: v2.3 Added configuration file per Tao’s suggestion. Thanks, Tao!
  • Added mail send logging.
  • Added LastModified field. The script adds the “LastModified” time to the email body. However, the script still takes a few more seconds to finish and right before it finishes, it updates the alert status to “Notified” thereby modifying the alert. If you look in the Console at the LastModified time, it won’t precisely match what is shown in the email notification; the Console will show a timestamp that is slightly more recent.
  • 2015.5.14: v2.2.3 Removed a few unnecessary lines/commands that could potentially cause script errors and/or failure
  • 2015.5.3: v2.2.2 Removed older style SCOM cmdlets, only 2012R2+ supported now.
  • 2015.5.1: v2.2.1 Added support to include Parent name (IP address) and ‘sysName’ properties for network devices into CustomField9 of alert, also included in notification.
  • Added Powershell code snippet to documentation below for setting registry value to increase asynchronous process limit.
  • 2015.3.12: Changed how the PSModulePath gets set.
  • 2015.1.30: Added additional detail to instructions section.
  • 2015.1.8: Added Subscriber schedule validation AND Subscriber Address schedule validation logic. Cleaned up a few minor typos.
  • 2014.12.2: Fixed a typo in the error logging output message.
  • 2014.10.17: Updated so that email body would contain customer field 4 (CF4) before sending the email for “New” alerts.
  • 2014.9.16: Update the subject line format.
  • 2014.8.19: Updated documentation with notes on email subscriptions overrides.

 

 

Email Critical Alert Format Example:

From: SCOM-Alert [mailto:NOREPLY@contoso.com]
Sent: Thursday, October 8, 2015 10:49 AM
To: Tyson Paul <Tyson@contoso.com>
Subject: New, TEST:MS02\http://gunbot.net/ammo/rimfire/22short/, HTTP Request Error: Content Validation Error

Severity: Critical Error

Severity: Critical Error
Alert Description: Content Validation Error

Monitor Settings:
URL: http://gunbot.net/ammo/rimfire/22short/
ContentMatch String: PUMPKINS
GroupID: URLGenie_Default
DNSResolutionTime: 0.1516305
Interval: 300
RetryCount: 1
Wiki: http://blogs.msdn.com/b/tysonpaul/archive/2015/05/04/urlgenie-management-pack-for-scom-an-easy-solution-for-bulk-website-monitoring.aspx
Description: Gunbot.net, Near realtime tracking of who has ammo, mags and reloading supplies in stock.

******* Request Headers *******
GET /ammo/rimfire/22short/ HTTP/1.1
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT; Windows NT 6.1; en-US)
Content-Type: text/xml;charset=utf-8
Accept-Language: en-US
Accept-Charset: utf-8
From: SCOM@yourdomain.com
Connection: Keep-Alive

******* End Request Headers *******

******* Response Headers *******
ResponseHeaders: HTTP/1.1 200 OK
Connection: close
Date: Thu, 08 Oct 2015 17:46:12 GMT
Content-Length: 4842
Content-Type: text/html; charset=UTF-8
Server: Apache/2.2.15 (CentOS)
X-Powered-By: PHP/5.3.3

******* End Response Headers *******

Command Channel: MyDev
Source: http://gunbot.net/ammo/rimfire/22short/
Path: MS02.Contoso.com;\\Db01.contoso.com\scom_do_not_touch\URLGenie
Principal Name: MS02.Contoso.com
Alert Name: HTTP Request Error: Content Validation Error
Alert Resolution State: New (0)
Alert Monitor Name: URLGenie Content Monitor
Alert Monitor Description: None
Time Raised: 10/08/2015 10:45:42
Last Modified: 10/08/2015 10:48:05
Alert ID: b88f30ec-b008-4fc5-b785-a19cc3646238

SCOM Operations Console Info:

Operations Console Login Info

SCOM Web Console link:

Web Console

Research It:

Bing It!
ADMIN DIAGNOSTIC INFO ——————–
**Use this command to view the full details of this alert in SCOM Powershell console: Get-SCOMalert -Id “b88f30ec-b008-4fc5-b785-a19cc3646238” | format-list *
This email sent from: MS01.Contoso.com
CF1: Alert.NetBIOSName: MS02
CF2: Alert.NetBIOSDomain Name: CONTOSO
CF3: Alert.PrincipalName: MS02.Contoso.com
CF4: SubscriberList: Subscribers:Subscriber1;
CF5: Management Pack Name: URLGenie Management Pack
CF6: Alert Class Name: URLGenie.HttpRequest
CF7: Alert.Category AvailabilityHealth
CF8: Workflow Type MONITOR
CF9: RESERVED
CF10: This Email Generated From C:\SCOM_SCRIPTS\Notifications\SCOMEnhancedEmailNotification_v2.2.4.ps1
Context: 
Note: This context data is only relevant to the moment/time at which this alert was sent.
type : Microsoft.SystemCenter.WebApplication.WebAp
plicationData
time : 2015-10-08T10:45:42.0960698-07:00
sourceHealthServiceId : 120875E8-C79E-91CA-E3AC-EA09A391F4BD
RequestResults : RequestResults
TransactionResponseTime : 0.270948
TransactionResponseTimeEvalResult : 0
CollectPerformanceData : CollectPerformanceData

 

Knowledge Article:


 

Summary

The context information for these alerts is not always helpful. To see more detailed information about this alert log into the console for the management group.

Wiki


Note:

The context information provided in this notification is limited and is not always helpful. To see more detailed information about this alert, log into the appropriate SCOM console for the applicable SCOM management group and use the Health Explorer to find more details about the state change event(s) for the object.

 

 

 

Closed Alert Example

From: SCOM-Alert [mailto:NOREPLY@contoso.com]
Sent: Thursday, October 8, 2015 3:32 PM
To: Tyson Paul <Tyson@contoso.com>
Subject: Closed, TEST:MS02\http://gunbot.net/ammo/rimfire/22short/, HTTP Request Error: Content Validation Error

Severity: Critical Error

Severity: Critical Error
Alert Description: Content Validation Error

Monitor Settings:
URL: http://gunbot.net/ammo/rimfire/22short/
ContentMatch String: PUMPKINS
GroupID: URLGenie_Default
DNSResolutionTime: 0.1516305
Interval: 300
RetryCount: 1
Wiki: http://blogs.msdn.com/b/tysonpaul/archive/2015/05/04/urlgenie-management-pack-for-scom-an-easy-solution-for-bulk-website-monitoring.aspx
Description: Gunbot.net, Near realtime tracking of who has ammo, mags and reloading supplies in stock.

******* Request Headers *******
GET /ammo/rimfire/22short/ HTTP/1.1
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT; Windows NT 6.1; en-US)
Content-Type: text/xml;charset=utf-8
Accept-Language: en-US
Accept-Charset: utf-8
From: SCOM@yourdomain.com
Connection: Keep-Alive

******* End Request Headers *******

******* Response Headers *******
ResponseHeaders: HTTP/1.1 200 OK
Connection: close
Date: Thu, 08 Oct 2015 17:46:12 GMT
Content-Length: 4842
Content-Type: text/html; charset=UTF-8
Server: Apache/2.2.15 (CentOS)
X-Powered-By: PHP/5.3.3

******* End Response Headers *******

Command Channel: MyDev
Source: http://gunbot.net/ammo/rimfire/22short/
Path: MS02.Contoso.com;\\Db01.contoso.com\scom_do_not_touch\URLGenie
Principal Name: MS02.Contoso.com
Alert Name: HTTP Request Error: Content Validation Error
Alert Resolution State: Closed (255)
Alert Monitor Name: URLGenie Content Monitor
Alert Monitor Description: None
Time Raised: 10/08/2015 10:45:42
Last Modified: 10/08/2015 15:30:32
Alert ID: b88f30ec-b008-4fc5-b785-a19cc3646238

SCOM Operations Console Info:

Operations Console Login Info

SCOM Web Console link:

Web Console

Research It:

Bing It!
ADMIN DIAGNOSTIC INFO ——————–
**Use this command to view the full details of this alert in SCOM Powershell console: Get-SCOMalert -Id “b88f30ec-b008-4fc5-b785-a19cc3646238” | format-list *
This email sent from: MS01.Contoso.com
CF1: Alert.NetBIOSName: MS02
CF2: Alert.NetBIOSDomain Name: CONTOSO
CF3: Alert.PrincipalName: MS02.Contoso.com
CF4: SubscriberList: Subscribers:Subscriber1;
CF5: Management Pack Name: URLGenie Management Pack
CF6: Alert Class Name: URLGenie.HttpRequest
CF7: Alert.Category AvailabilityHealth
CF8: Workflow Type MONITOR
CF9: RESERVED
CF10: This Email Generated From C:\SCOM_SCRIPTS\Notifications\SCOMEnhancedEmailNotification_v2.2.4.ps1
Context: 
Note: This context data is only relevant to the moment/time at which this alert was sent.
type : Microsoft.SystemCenter.WebApplication.WebAp
plicationData
time : 2015-10-08T15:30:32.3385560-07:00
sourceHealthServiceId : 120875E8-C79E-91CA-E3AC-EA09A391F4BD
RequestResults : RequestResults
TransactionResponseTime : 0.1240154
TransactionResponseTimeEvalResult : 0
CollectPerformanceData : CollectPerformanceData

 

Knowledge Article:


 

Summary

The context information for these alerts is not always helpful. To see more detailed information about this alert log into the console for the management group.

Wiki


Note:

The context information provided in this notification is limited and is not always helpful. To see more detailed information about this alert, log into the appropriate SCOM console for the applicable SCOM management group and use the Health Explorer to find more details about the state change event(s) for the object.

 

Directions:

In the script there are instructions at the top that describe a few of the settings (lines of code) that must be configured before use. Simply edit the “Settings” area within the script. Use Notepad or your favorite text editor. I like Powershell ISE or Notepad++ .
Configuration is very simple and there are examples for each setting within the script comments at the top.

 

Here’s what I recommend:
PERFORM THESE TEST PROCEDURES IN A LAB ENVIRONMENT (NON PRODUCTION):

Remove all management servers from your Notifications Resource Pool except for one single server. This will help you troubleshoot during testing if needed.

Create this folder on your test mgmt server: “C:\SCOM_SCRIPTS\Notifications

Put the script into that new folder.

Open the Config.xml file and customize the necessary fields: smtp server, port, smtp sender, web console url, etc.  See the example files also in the folder. This Config.xml file must be located in the same directory as the .SCOMEnhancedEmailNotification.ps1 script. I suggest you put these files in this path on your management servers:   C:\SCOM_SCRIPTS\Notifications

Make sure that your default action account is a local administrator on your test mgmt server.

Make sure that your Powershell execution policy is not blocking the command channel execution.

  • View policy: Get-ExecutionPolicy 
  • Or just run the following to be sure the policy is “unrestricted”. In an elevated Powershell console on the mgmt server, run this command:
    Set-ExecutionPolicy Unrestricted
  • Note: a reboot may be necessary after modifying the execution policy.

 

 

Create the command channel:

Field  Parameter Notes
Full path of the command file: %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe Standard path to Powershell.exe (all versions)
Command line parameters: C:\SCOM_SCRIPTS\Notifications\SCOMEnhancedEmailNotification.ps1 -Description ‘MyDev’ -alertID ‘$Data/Context/DataItem/AlertId$’ -SubscriptionID ‘$MPElement$’  * IF additional Ops Manager event log details are desired,  use the -Verbose switch in the command line.
Startup folder for the command line: C:\SCOM_SCRIPTS\Notifications

 

 

 

Note: due to the encoding of this blog page, if using copy/paste the single and double quotation marks may need to be replaced manually once copied to your server.

CommandChannel1

 

 

Subscribers:

  • Create a Test Subscriber with your email address. You can configure multiple subscribers, each with one or more recipients. The script will send to To, CC, and BCC. Notice the “TO” and “CC” preceding the addresses. If “TO”, “CC”, or “BCC” are omitted, the default becomes “TO”.

 

 


 Subscriptions:

 

 

  • Pick one or more “Subscribers”

 

 

New! Added support for schedules on Subscriber and individual Addresses.

Note: ANY Exclusions will take precedence over any Inclusions.

Testing:

  • Generate a test alert with this command from regular command prompt (not Powershell console), paste the following into command window:EventCreate /T ERROR /ID 101 /L APPLICATION /SO TEST /D “This is a synthetic transaction test only. Disregard this event. Note: This alert was generated by entering the below command into a command pompt on the server in question:> EventCreate /T ERROR /ID 101 /L APPLICATION /SO TEST /D

 

  • Watch Task Manager on the test mgmt server, look for a Powershell.exe process to spin up. Usually the process will take 10 – 20 seconds to send the mail.
  • You may want to adjust your max asynchronous process limit for Powershell as described here:
    http://www.scomnifties.com/powershell-script-to-set-asynchronous-process-limit-on-management-servers/
  • You should receive the email quickly if you configured everything correctly.
  • Copy the script folder to your other management servers that will be in the Notifications Resource Pool. It must be in the same path on each mgmt. server.
  • Put each management server alone in the Notifications Resource Pool, one at a time,  and test each with the Synthetic Transaction procedure described above.

Troubleshooting:

If the script doesn’t appear to be running, open Task Manager, sort by Name, and watch for a new Powershell.exe process to spin up under the Management Server Action Account context/user . The script takes from 10-20 seconds to complete. If the new Powershell.exe process doesn’t open within 60 seconds or opens briefly and then disappears, then you have a problem.

Make sure the script itself is not being blocked from running. Right-click the script, select Properties. If you see a “Unblock” button, click it to make sure the script is not being blocked from execution.

The Powershell execution policy may be Restricted. Change this to Unrestricted. Set-ExecutionPolicy Unrestricted

There may be an error with the Channel configuration or path(s). Double check the path to the .ps1 script. Make sure the full file path is precise. I suggest navigating to the actual path where the script lives and copying the full path right from the File Explorer address/path field. This way there’s no chance of misspelling the path to the script. See command line parameter field example above.

Check the Notifications folder for any errors that might appear in the error log. Use the -Verbose and -WriteToEventLog command line parameter switches for additional Ops Manager event logging detail.

If needed, you can manually run the script. You must first set the required variables near the top of the script.

############### UNCOMMENT FOR MANUAL TESTING ############
 # $Description = "ManualTest"
 # $alertID = (Get-SCOMAlert)[0].ID.Guid

# Create a test subscription with “Synthetic” in the name
# $SubscriptionID = (Get-SCOMNotificationSubscription -DisplayName *Synthetic* ).ID.Guid

# $Verbose = $true
################## FOR TESTING ##########################

An additional method to gain visibility into any errors that might occur (before the script has a chance to write error output to the event log) is to append the line shown directly below at the end of the command line parameters:

 ; Write-Output “$($Error)” |  Out-File -Filepath C:\SCOM_SCRIPTS\Notification_Errors.txt

Example:

“C:\SCOM_SCRIPTS\Notifications\SCOMEnhancedEmailNotification.ps1” -Description “MyDev” -alertID ‘$Data/Context/DataItem/AlertId$’ -SubscriptionID ‘$MPElement$’  -ErrorLogFile “C:\SCOM_SCRIPTS\Errors.log” -Verbose -WriteToEventLog ; Write-Output “$($Error)” |  Out-File -Filepath C:\SCOM_SCRIPTS\Notification_Errors.txt

This will output any errors that occur when the workflow attempts to launch the command channel.

Also, I’ve seen some weird things happen when copying/pasting from online sources into Powershell scripts. Make sure you are not copying some weirdly encoded characters. I’m pretty sure this blog doesn’t use any strange encoding but to keep your sanity, copy the code portions into Notepad++ and force the encoding to be UTF-8, then copy from there into the Console wizard.

*Please let me know if you have any suggestions to improve this article.

 

 

Page History:

  • 2015/11/5: Updated the email examples. Updated the configuration instructions.
  • 2015/5/14: Cleaned up some of the text. Added script version history near top.
  • 2014/9/16: Updated script. Improved notification subject line format.
  • 2014/10/15: Updated command channel arguments examples, removed some quotes
  • 2014/10/17: Updated troubleshooting section. Also updated the script to add the Subscribers to the CF4 field on “New” alerts. Previously subscribers would be empty for new alerts.
  • 2014/10/27: Updated troubleshooting section.
  • 2014/10/29: Updated some sloppy grammar.

 

Disclaimer: Sample scripts in this guide are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages.


Comments (41)

  1. Cookie.Monster says:

    Hi Tyson,

    Good stuff, I'm a fan of Tao's idea!

    Question for you – how does SCOM handle concurrency with this notification channel?  In a hypothetical situation with 10 alerts at once, would we end up with 10 PowerShell.exe processes, or do you use any special threading or runspaces if you see powershell.exe as the command file?

    Thanks!

    rcm

  2. Tyson.Paul says:

    Each instance of the command channel is separate. In the comment/instructions are at the top of the script there is information on how to increase the "asynchronous" process limit. I usually set mine to 20 on mgmt servers but this would depend on your server specs.

  3. Recep YUKSEL - TAT says:

    Thank you Tyson.

  4. Regis says:

    Hello,

    Where is the script itself ?

  5. Tyson.Paul says:

    I somehow lost the link when I added the disclaimer. The link has been fixed.

  6. Tyson.Paul says:

    I just added some additional details to the Directions section.

  7. Jason says:

    How would I go about adding the Alert Name to the subject line?

  8. Tyson.Paul says:

    Hi Jason,

      The commented line should/could probably be uncommented. The “If” block below it basically will determine if the “Path” of the alerting instance includes the FQDN of a server, if yes, will include the PathName in the subject. The commented line could be uncommented to act as a default in case the path does not include a FQDN. Both assignment statements include the AlertName although at the tail end of the subject. If you wanted the AlertName to be near the beginning of the subject so as to be more easily readable in a cramped email window/screen see the revised code block below.

    ORIGINAL (blog formatting might ruin this code block):

    #$strSubject = "$strResStateName, $($Description):" + "$strAgentName$AlertSource, $strAlertName"

    If( (([regex]::matches($pathName,".").count -eq 2) -or ([regex]::matches($pathName,".").count -eq 3) ) -and (!( ($pathName -match '/') -or ($pathName -match '\'))) ) {

               $strSubject = "$strResStateName, $($Description): " + "$($pathName) $AlertSource, $strAlertName"

    }

    REVISED: (blog formatting might ruin this code block):

    $strSubject = "$($strResStateName), $($strAlertName):" + "$($strAgentName)$($AlertSource)"

    If( (([regex]::matches($pathName,".").count -eq 2) -or ([regex]::matches($pathName,".").count -eq 3) ) -and (!( ($pathName -match '/') -or ($pathName -match '\'))) ) {

               $strSubject = "$($strResStateName), $($strAlertName): " + "$($pathName)$($AlertSource)"

    }

  9. Tyson.Paul says:

    Jason:  I have since updated the script with the revised subject line formatting.

  10. Robert Romig says:

    I can't seem to get this script to work.  If I put the external email address in as the one to use for error reporting, that message goes through.  However, if I try to use this as an additional notification channel for an existing subscription, it doesn't work.

  11. Tyson.Paul says:

    Hi Robert,

       You haven't given me a ton of detail about your current configuration or what the error email contained so it's difficult to diagnose from here. Please have a look at the Troubleshooting section of the post. I just added

    a few more suggestions.

    If you still can't get it working, send me your script with your customized

    settings (minus any email account password) and I'll look it over to see if I can spot anything that might need tweaking.

  12. Mathew Perkins says:

    Hi Tyson!

    Thanks for the script, working very well! However I am having a weird issue with the emails being sent. It seems that the alert emails ALWAYS send a second alert, exactly the same as the first, about a minute or so after the first has been received. Since we are sending this to our servicedesk program this creates a double of every job logged by SCOM. Any idea why this might be happening?

    Sincerely

    Mathew Perkins

  13. Tyson.Paul says:

    @Mathew,

      My guess is that the you need to modify your subscription criteria to only send alerts for "New" and/or "Closed" alerts. When the script runs it changes the alert Resolution State to "Notified" (ID value: 2), which updates the alert. When alerts get updated in any way, they are flagged to be processed (again) by the notifications/subscriptions workflows. If the subscription criteria is already correct, then make sure that you actually created the Alert Resolution State "Notified" , ID: 2, in the Administration workspace , Settings->Alerts window in the Console. You should be seeing the Resolution State change to "Notified" in the Alert view.

  14. Mathew Perkins says:

    Ohhh! I think I just figured out why this is happening.

    I have set the subscriptions to only alert on new or closed alerts, not updated ones. And I have also created the ID:2 n(otified) as a customer resolution state in SCOM. However, the way I am using this is a little different. When a "new" alert comes in, the script does not kick off, we do not want to send EVERY alert that comes in, to servicedesk. Instead, I have set the command channel to run, when it notices a new job with the resolution state of 2 (notified) this way, I can keep scom open, right click and set the resolution state of the jobs that need to go through to the servicedesk manually. After I do this manually, it runs the command channel, runs the script, which AGAIN updates the alert status to 2 (notified) and the script runs again, does this sound right?

    I may need to change the settings a little to fit with what I am trying to achieve. However I am unsure of how to do this.

  15. Tyson.Paul says:

    @Mathew,

      You stated that your subscription is configured to notify on New or Closed but not updated. If the current ResolutionState of an alert is New or Closed and you update it in some way (other than changing the ResolutionState to something other than New/Closed), the alert will be flagged again internally for a subscription criteria check. If any subscription criteria matches, the corresponding channel will get kicked off, whatever that channel is (SMTP, Command, etc.). So I don't understand your first statement.

    I think I understand what you are trying to accomplish. Let me state what I suspect you are after:

    –  When a New alert is created, do nothing.

    –  When the ResolutionState is manually changed to whatever the ID is for "pending Service Desk investigation" (ServiceDesk, PendingSvcDesk, etc.) trigger command channel as usual. (Alert is touched/updated internally, subscription check is triggered, and an Email gets sent)

    –  When alert ResolutionState changes to Closed, trigger command channel as usual.  (Alert is touched/updated internally, subscription check is triggered, and an Email gets sent)

    If this is correct, do the following:

    Create an alert ID specifically for "pending Service Desk". Name it something like, "ServiceDesk" and give it an ID of say… 3.

    Configure your subscription to trigger on these ResolutionStates ONLY: ServiceDesk, and Closed.

    The script will only change ResolutionState from New to Notified IF the ResolutionState is currently New. In the case described above, the script will not trigger from New alerts. Once you change it manually from New to ServiceDesk, it will stay set to ServiceDesk until you change it again manually or until it auto-closes (if source=Monitor, not Rule). Does that make sense?

  16. Mathew Perkins says:

    Thanks so much Tyson!

    I got this working a little while ago, have fully tested it and implemented into production. Great script, thanks for all the hard work!

    Sincerely

    Mathew Perkins

  17. jon Berg says:

    Hi

    I look at alert notification for network and then some information is missin. For be able to see name of the device "Full pathname" need to be added, and port see port number "Description" in entinty properites. Description display portnumber like Ethernet1/31.

    Can this be added to the script?

    Regards

    Jon

  18. Tyson.Paul says:

    Hi Jon,

       You can edit the script yourself and add the following values wherever you want using the following format:

    Port Number:

    (Get-SCOMClassInstance -Id $monitoringObjectId).'[System.NetworkManagement.Node].PortNumber'.Value

    SNMPAddress:

    (Get-SCOMClassInstance -Id $monitoringObjectId).'[System.NetworkManagement.Node].SNMPAddress'.Value

  19. Phillip Green says:

    I am trying to configure this in my environment and get only the e-mail telling me there was an error executing the script:

    Alert Resolution State:

    **Note:Error will occur if the script tries to process an alert with Resolution State other than New.

    The alert resolution state is definitely New; I checked that.

    I get a log file generated that shows the following:

    ============================== BEGIN: 02/11/2015 12:59:35 ==============================

    ============================== BEGIN: 02/11/2015 12:59:35 ==============================

    alert.NetBiosComputername:

    alert.PrincipalName:

    Class.name:

    TempFilePath: C:WindowsTEMPtmpEB14.tmp

    Mailmessage: System.Net.Mail.MailMessage

    You cannot call a method on a null-valued expression. You cannot call a method on a null-valued expression. You cannot call a method on a null-valued expression. The property 'CustomField10' cannot be found on this object. Verify that the property exists and can be set. The property 'CustomField9' cannot be found on this object. Verify that the property exists and can be set. The property 'CustomField8' cannot be found on this object. Verify that the property exists and can be set. The property 'CustomField7' cannot be found on this object. Verify that the property exists and can be set. The property 'CUstomField6' cannot be found on this object. Verify that the property exists and can be set. Cannot validate argument on parameter 'DisplayName'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again. Cannot bind argument to parameter 'Id' because it is null. The property 'CustomField3' cannot be found on this object. Verify that the property exists and can be set. The property 'CustomField2' cannot be found on this object. Verify that the property exists and can be set. The property 'CustomField1' cannot be found on this object. Verify that the property exists and can be set. You cannot call a method on a null-valued expression. You cannot call a method on a null-valued expression. You cannot call a method on a null-valued expression. You cannot call a method on a null-valued expression. You cannot call a method on a null-valued expression. You cannot call a method on a null-valued expression. You cannot call a method on a null-valued expression.

    ============================== END: 02/11/2015 12:59:35 ==============================

    alert.NetBiosComputername:

    alert.PrincipalName:

    Any suggestions?

    1. Stevan davis says:

      what was the solution, I am having the same problem? 2016-12-02_16:11:47.732 alert.NetBiosComputername:
      alert.PrincipalName:

      Class.name:

      TempFilePath: C:\Windows\TEMP\tmpC300.tmp Cannot bind argument to parameter ‘ResolutionStateCode’ because it is null. You cannot call a method on a null-valued expression. You cannot call a method on a null-valued expression. You cannot call a method on a null-valued expression. The property ‘CustomField10’ cannot be found on this object. Verify that the property exists and can be set. You cannot call a method on a null-valued expression. Cannot validate argument on parameter ‘Class’. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again. The property ‘CustomField9’ cannot be found on this object. Verify that the property exists and can be set. The property ‘CustomField8’ cannot be found on this object. Verify that the property exists and can be set. The property ‘CustomField7’ cannot be found on this object. Verify that the property exists and can be set. The property ‘CUstomField6’ cannot be found on this object. Verify that the property exists and can be set. Cannot validate argument on parameter ‘DisplayName’. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again. Cannot bind argument to parameter ‘Id’ because it is null. The property ‘CustomField3’ cannot be found on this object. Verify that the property exists and can be set. The property ‘CustomField2’ cannot be found on this object. Verify that the property exists and can be set. The property ‘CustomField1’ cannot be found on this object. Verify that the property exists and can be set. You cannot call a method on a null-valued expression. You cannot call a method on a null-valued expression. You cannot call a method on a null-valued expression. You cannot call a method on a null-valued expression. The user MDYNYCMAS\Sys_dev_scomaa does not have sufficient permission to perform the operation. You cannot call a method on a null-valued expression. You cannot call a method on a null-valued expression. The user MDYNYCMAS\Sys_dev_scomaa does not have sufficient permission to perform the operation.

      1. Tyson.Paul says:

        Looks like your mgmt server action account account is having some permission issue accessing/updating the alert data. This might sound too simple but I’ve seen this before and a restart of your mgmt server (whichever one is the current notification server nominee) will probably solve it. If you don’t know which server is running the notification workflow, just reboot all of them, one at a time (those that are in the Notification pool).

      2. Tyson.Paul says:

        Reboot your mgmt servers and make sure SQL service is running on your SCOM DB server(s).

  20. Phillip Green says:

    Following the troubleshooting guide, I get this information in the notification_errors file:

    Remove-Variable : Cannot find a variable with the name 'WhatIfPreference'.

    At S:SCOM_SCRIPTSNotificationsSCOMEnhancedEmailNotification_v2.2.ps1:353

    char:79

    +     Get-Variable | Where-Object { $StartupVariables -notcontains $_.Name } |

    % { Re …

    +                                                                              

       ~~

       + CategoryInfo          : ObjectNotFound: (WhatIfPreference:String) [Remov

      e-Variable], ItemNotFoundException

       + FullyQualifiedErrorId : VariableNotFound,Microsoft.PowerShell.Commands.R

      emoveVariableCommand

    Remove-Variable : Cannot find a variable with the name 'WarningPreference'.

    At S:SCOM_SCRIPTSNotificationsSCOMEnhancedEmailNotification_v2.2.ps1:353

    char:79

    +     Get-Variable | Where-Object { $StartupVariables -notcontains $_.Name } |

    % { Re …

    +                                                                              

       ~~

       + CategoryInfo          : ObjectNotFound: (WarningPreference:String) [Remo

      ve-Variable], ItemNotFoundException

       + FullyQualifiedErrorId : VariableNotFound,Microsoft.PowerShell.Commands.R

      emoveVariableCommand

    Remove-Variable : Cannot find a variable with the name 'VerbosePreference'.

    At S:SCOM_SCRIPTSNotificationsSCOMEnhancedEmailNotification_v2.2.ps1:353

    char:79

    +     Get-Variable | Where-Object { $StartupVariables -notcontains $_.Name } |

    % { Re …

    +                                                                              

       ~~

       + CategoryInfo          : ObjectNotFound: (VerbosePreference:String) [Remo

      ve-Variable], ItemNotFoundException

       + FullyQualifiedErrorId : VariableNotFound,Microsoft.PowerShell.Commands.R

      emoveVariableCommand

    Remove-Variable : Cannot remove variable true because it is constant or

    read-only. If the variable is read-only, try the operation again specifying

    the Force option.

    At S:SCOM_SCRIPTSNotificationsSCOMEnhancedEmailNotification_v2.2.ps1:353

    char:79

    +     Get-Variable | Where-Object { $StartupVariables -notcontains $_.Name } |

    % { Re …

    +                                                                              

       ~~

       + CategoryInfo          : WriteError: (true:String) [Remove-Variable], Ses

      sionStateUnauthorizedAccessException

       + FullyQualifiedErrorId : VariableNotRemovable,Microsoft.PowerShell.Comman

      ds.RemoveVariableCommand

  21. Tyson.Paul says:

    Hi Phillip,

      This is an interesting problem. I can't imagine why that line in the Cleanup function is giving you grief. I'm curious which version of Powershell you have on your notification server. In the meantime, you could try to comment out the line# 988 where the Cleanup function is being called. Or comment out line 353 which is where the command is called to remove the session variables. Cleaning up the variables is not entirely necessary in Powershell but it's generally accepted as good coding etiquette and makes for a more consistent experience across a number of hosts.

  22. Anonymous says:

    Hi Tyson, thanks for the script.

    Would it be possible to add to the close notification the "Last Modified by" field? We usually have several agents using the scom and we would like to keep track of who closed the alerts.

    Thanks for your help.

  23. Tyson.Paul says:

    @Mike Justice:  Probably. I currently have a customer request to add some functionality to this script so I'll probably add this in at the same time. (probably within the next week or two)

  24. Anonymous says:

    Hi ,

    Thank you for your great job..

    I have the following error generated by script. would you please advise me,,, Any suggestions?

    Exception calling "Substring" with "2" argument(s): "Index and length must refer to a location within the string.

    Parameter name: length"

    At C:SCOM_SCRIPTSNotificationsSCOMEnhancedEmailNotification_v2.2.3.ps1:415 char:5

    + If ($alertID.substring(0,1) -match "{") { $alertID = $alertID.substring(1, ( $al …

    +     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

       + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException

       + FullyQualifiedErrorId : ArgumentOutOfRangeException

    Exception calling "Substring" with "2" argument(s): "StartIndex cannot be less than zero.

    Parameter name: startIndex"

    At C:SCOM_SCRIPTSNotificationsSCOMEnhancedEmailNotification_v2.2.3.ps1:416 char:5

    + If ($alertID.substring(($alertID.length -1), 1) -match "}") { $alertID = $alertI …

    +     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

       + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException

       + FullyQualifiedErrorId : ArgumentOutOfRangeException

    New-SCManagementGroupConnection : A parameter cannot be found that matches parameter name 'ConnectionString'.

    At C:SCOM_SCRIPTSNotificationsSCOMEnhancedEmailNotification_v2.2.3.ps1:477 char:35

    + new-SCOMmanagementGroupConnection -ConnectionString:$MYFQDN | Out-Null

    +                                   ~~~~~~~~~~~~~~~~~~

       + CategoryInfo          : InvalidArgument: (:) [New-SCManagementGroupConnection], ParameterBindingException

       + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.SystemCenter.Core.Commands.NewSCManagementGroupConnectionCommand

  25. Matthew Raida says:

    Hello,

    I'm utilizing this script and it works great!  I have a client that I created a extended AD Class to included the description of the server from AD.  How would I add the description to the script?

    The class is Windows.Computer_Extended

  26. Tyson.Paul says:

    @Matthew Raida: I see what you are trying to do here but this could be tricky because not every alert has a "path" ($alert.MonitoringObjectPath). I suppose you could simply TRY to get the path and, if it exists in the form of an FQDN, attempt to compare it to your custom objects and if there is a match then display the AD custom property/note of the matching custom object.

    -Tyson

  27. Matthew Raida says:

    Thanks Tyson,

    I don't have a problem with that cause most have a path.  Any idea how I can utilize this script to pull from the extended class?

    Thanks,

    Matthew Raida

  28. Tyson.Paul says:

    @Matthew Raida:

    Can you contact me directly via the "Email Blog Author" link at the top? Let's continue this over email. I might be able to point you in the right direction.

  29. salmonjr says:

    Excellent work on the script! It's great to have an option like this since it's not built in to SCOM (especially one that's been kept up to date with fixes and features added along the way).

    That seems to be a commonality with System Center products. SCCM is the same way, except you have even less options as far as configurable email alerts go. And all these alerts from either system with little to no customization is in my opinion, pretty terrible.

    Maybe we'll see improvements in 2016.

  30. Dhanveer Ahamed says:

    Hi All,

    I am getting the below errors, I am not able to find a solution for the below errors. Can anyone help me with the below errors with the above script.

    2015-12-13_08:47:03.498 SUCCESS outlook.AFG.alfaraa.com "SCOM.Service" <SCOM.Service@alfaraa.com> C:ScriptsSCOMEnhancedEmailNotification.ps1 XXXXX alert.NetBiosComputername: ,  alert.PrincipalName: ,  Class.name: ,  TempFilePath: C:UsersScom.ServiceAppDataLocalTemp2tmpC260.tmp Cannot bind argument to parameter 'ResolutionStateCode' because it is null. You cannot call a method on a null-valued expression. You cannot call a method on a null-valued expression. You cannot call a method on a null-valued expression. Property 'CustomField10' cannot be found on this object; make sure it exists and is settable. You cannot call a method on a null-valued expression. Cannot validate argument on parameter 'Class'. The argument is null or empty. Supply an argument that is not null or empty and then try the command again. Property 'CustomField9' cannot be found on this object; make sure it exists and is settable. Property 'CustomField8' cannot be found on this object; make sure it exists and is settable. Property 'CustomField7' cannot be found on this object; make sure it exists and is settable. Property 'CUstomField6' cannot be found on this object; make sure it exists and is settable. Cannot validate argument on parameter 'DisplayName'. The argument is null or empty. Supply an argument that is not null or empty and then try the command again. Cannot bind argument to parameter 'Id' because it is null. Property 'CustomField3' cannot be found on this object; make sure it exists and is settable. Property 'CustomField2' cannot be found on this object; make sure it exists and is settable. Property 'CustomField1' cannot be found on this object; make sure it exists and is settable. You cannot call a method on a null-valued expression. You cannot call a method on a null-valued expression. You cannot call a method on a null-valued expression. You cannot call a method on a null-valued expression. Cannot bind parameter 'Id'. Cannot convert value "" to type "System.Guid". Error: "Unrecognized Guid format." You cannot call a method on a null-valued expression. You cannot call a method on a null-valued expression. Cannot bind parameter 'Id'. Cannot convert value "" to type "System.Guid". Error: "Unrecognized Guid format."

  31. Pavel says:

    The same problem with script

    Get-SCOMAlert : Cannot bind parameter 'Id'. Cannot convert value "$Data/Context/DataItem/AlertId$" to type "System.Guid". Error: "Guid should contain 32

    digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).

    I did manual test and it is not work

    Exception calling "GetKnowledgeArticle" with "1" argument(s): "The requested management pack knowledge article was not found."

    At C:SCOMEnhancedEmailNotification_2.3SCOMEnhancedEmailNotification.ps1:514 char:3

    +         $article = $monitor.GetKnowledgeArticle($cultureInfo)

    +         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

       + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException

       + FullyQualifiedErrorId : ObjectNotFoundException

  32. Jeff says:

    Will script version 2.3 work in a SCOM 2007 R2 environment?

      1. Jeff says:

        Thank you.

      2. Jeff says:

        Where can I download 2.1? Is there a doc that goes along with it? I’m not crazy strong in Powershell. Thanks!

  33. Sylvr317 says:

    I was able to get this working in our environment right away. Nicely tested and it’s rock solid. My question is if I wanted to call another script from this script where I would pass the AlertID to it as a parameter, and to pull information from the second script to include in the email, where in the logic should I do that? Ive been experimenting and I’m not sure I’m truly following the flow. Would you mind helping?
    Thanks

    1. Tyson.Paul says:

      @Sylvr317
      You could do this anytime before building the html body. Then insert the data into the appropriate location within the body; I’m guessing that you would want to add a row to an existing table. However, it might make more sense to bake the code directly into the main script instead of calling a separate script. What info are you trying to add to the email?

      1. Sylvr317 says:

        The script just uses a bunch of high level descriptive stuff that you would want in the ticket. Jira is the ticketing tool and there are about 10 fields that we put information into. But most are hard coded. Right now I’m just wanting to grab the description and use that in the ticket summary. We are using REST logic to create the incident. It replies back with Incident ID, Key and URL of the ticket itself.
        We want to put that URL into the alert email that goes out after the ticket is created. Right now we are focused on physical and VM servers for this subscription action, so we will be including the link to our Wiki page for whatever server or vm has generated the error.