Step-by-Step: How to Trigger an Email Alert from a Windows Event that Includes the Event Details using Windows Server 2016

Introduction

Setting up an email alert is as simple as creating a Windows Task that is triggered by an Event. You then must specify the action that will occur when that Task is triggered. Since Microsoft has decided to deprecate the “Send an e-mail” option the only choice we have is to Start a Program. In our case that program will be a Powershell script that will collect the Event Log information and parse it so that we can send an email that includes important Log Event details.

This work was verified on Windows Server 2016, but I suspect it should work on Windows Server 2012 R2 and Windows Server 2019 as well. If you get it working on any other platforms please comment and let us know if you had to change anything.

Step 1 – Write a Powershell Script

The first thing that you need to do is write a Powershell script that when run can send an email. While researching this I discovered many ways to accomplish this task, so what I’m about to show you is just one way, but feel free to experiment and use what is right for your environment.

In my lab I do not run my own SMTP server, so I had to write a script that could leverage my Gmail account. You will see in my Powershell script the password to the email account that authenticates to the SMTP server is in plain text. If you are concerned that someone may have access to your script and discover your password then you will want to encrypt your credentials. Gmail requires and SSL connection so your password should be safe on the wire, just like any other email client.

Here is an example of a Powershell script that when used in conjunction with Task Scheduler which will send an email alert automatically when any specified Event is logged in the Windows Event Log. In my environment I saved this script to C:\Alerts\DataKeeper.ps1

$EventId = 16,20,23,150,219,220

$A = Get-WinEvent -MaxEvents 1  -FilterHashTable @{Logname = "System" ; ID = $EventId}
$Message = $A.Message
$EventID = $A.Id
$MachineName = $A.MachineName
$Source = $A.ProviderName


$EmailFrom = "sios@medfordband.com"
$EmailTo = "sios@medfordband.com"
$Subject ="Alert From $MachineName"
$Body = "EventID: $EventID`nSource: $Source`nMachineName: $MachineName `nMessage: $Message"
$SMTPServer = "smtp.gmail.com"
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
$SMTPClient.EnableSsl = $true
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("sios@medfordband.com", "mySMTPP@55w0rd");
$SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body)

An example of an email generated from that Powershell script looks like this.

Email1

You probably noticed that this Powershell script uses the Get-WinEvent cmdlet to grab the most recent Event Log entry based upon the LogName, Source and eventIDs specified. It then parses that event and assigns the EventID, Source, MachineName and Message to variables that will be used to compose the email. You will see that the LogName, Source and eventIDs specified are the same as the ones you will specify when you set up the Scheduled Task in Step 2.

Step 2 – Set Up a Scheduled Task

In Task Scheduler Create a Task as show in the following screen shots.

  1. Create Task
    Create Task

    Make sure the task is set to Run whether the user is logged on or not.
    DataKeeper Alerts

  2.  On the Triggers tab choose New to create a Trigger that will begin the task “On an Event”. In my example I will be creating an event that triggers any time DataKeeper (extmirr) logs an important event to the System log.
    Create Task 3
    Create a custom event and New Event Filter as shown below…

    Create Task - Trigger

    For my trigger I am triggering on commonly monitored SIOS DataKeeper (ExtMirr) EventIDs 16, 20, 23,150,219,220 . You will need to set up your event to trigger on the specific Events that you want to monitor. You can put multiple Triggers in the same Task if you want to be notified about events that come from different logs or sources.

    Edit Event Filter
    Create a New Event Filter

     

  3. Once the Event Trigger is configured, you will need to configure the Action that occurs when the event is run. In our case we are going to run the Powershell script that we created in Step 1.
    Actions - 2

    Edit - Actions

  4. The default Condition parameters should be sufficient.
    Conditions - 1
  5. And finally, on the Settings tab make sure you allow the task to be run on demand and to “Queue a new instance” if a task is already running.

    2018-10-28_00-17-27

Step 3 (if necessary) – Fix the Microsoft-Windows-DistributedCOM Event ID: 10016 Error

In theory, if you did everything correctly you should now start receiving emails any time one of the events you are monitoring gets logged in the event log.  However, I ran into a weird permission issue on one of my servers that I had to address before everything worked. I’m not sure if you will run into this issue, but just in case here is the fix.

In my case when I manually triggered the event, or if I ran the Powershell script directly, everything worked as expected and I received an email. However, if one of the EventIDs being monitored was logged into the event log it would not result in an email being sent. The only clue I had was the Event ID: 10016 that was logged in my Systems event log each time I expected the Task Trigger to detect a logged event.

Log Name: System
Source: Microsoft-Windows-DistributedCOM
Date: 10/27/2018 5:59:47 PM
Event ID: 10016
Task Category: None
Level: Error
Keywords: Classic
User: DATAKEEPER\dave
Computer: sql1.datakeeper.local
Description:
The application-specific permission settings do not grant Local Activation permission for the COM Server application with CLSID 
{D63B10C5-BB46-4990-A94F-E40B9D520160}
and APPID 
{9CA88EE3-ACB7-47C8-AFC4-AB702511C276}
to the user DATAKEEPER\dave SID (S-1-5-21-25339xxxxx-208xxx580-6xxx06984-500) from address LocalHost (Using LRPC) running in the application container Unavailable SID (Unavailable). This security permission can be modified using the Component Services administrative tool.

Many of the Google search results for that error indicate that the error is benign and include instructions on how to suppress the error instead of fixing it. However, I was pretty sure this error was the cause of my current failure to be able to send an email alert from a Scheduled Event that was triggered from a monitored Event Log entry, so I needed to fix it.

After much searching, I stumbled upon this newsgroup discussion.  The response from Marc Whittlesey pointed me in the right direction. This is what he wrote…

There are 2 registry keys you have to set permissions before you go to the DCOM Configuration in Component services: CLSID key and APPID key.

I suggest you to follow some steps to fix issue:

1. Press Windows + R keys and type regedit and press Enter.
2. Go to HKEY_Classes_Root\CLSID\*CLSID*.
3. Right click on it then select permission.
4. Click Advance and change the owner to administrator. Also click the box that will appear below the owner line.
5. Apply full control.
6. Close the tab then go to HKEY_LocalMachine\Software\Classes\AppID\*APPID*.
7. Right click on it then select permission.
8. Click Advance and change the owner to administrators.
9. Click the box that will appear below the owner line.
10. Click Apply and grant full control to Administrators.
11. Close all tabs and go to Administrative tool.
12. Open component services.
13. Click Computer, click my computer, and then click DCOM.
14. Look for the corresponding service that appears on the error viewer.
15. Right click on it then click properties.
16. Click security tab then click Add User, Add System then apply.
17. Tick the Activate local box.

So use the relevant keys here and the DCOM Config should give you access to the greyed out areas:
CLSID {D63B10C5-BB46-4990-A94F-E40B9D520160}

APPID {9CA88EE3-ACB7-47C8-AFC4-AB702511C276}

I was able to follow Steps 1-15 pretty much verbatim. However, when I got to Step 16 I really couldn’t tell exactly what he wanted me to do. At first I granted the DATAKEEPER\dave user account Full Control to the RuntimeBroker, but that didn’t fix things. Eventually I just selected “Use Default” on all three permissions and that fixed the issue.

RuntimeBroker
I’m not sure how or why this happened, but I figured I better write it all down in case it happens again because it took me a while to figure it out.

Step 4 – Automating the Deployment

If you need to enable the same alerts on multiple systems you can simply export your Task to an XML file and Import it on your other systems.

ExportImport

Or even better yet, automate the Import as part of your build process through a Powershell script after making your XML file available on a file share as shown in the following example.

PS C:\> Register-ScheduledTask -Xml (get-content '\\myfileshare\tasks\DataKeeperAlerts.xml' | out-string) -TaskName "DataKeeperAlerts" -User datakeeper\dave -Password MyDomainP@55W0rd –Force

 

In Summary

Hopefully what I have provided will give you everything you need to start receiving alert notification emails on whichever Event Log entries keep you up at night.

In my next post I will show you how to be notified when a specified Service either starts or stops. Of course you could just monitor for EventID 7036 from Service Control Monitor, but that would notify you whenever ANY service starts or stops. We will need to dig a little deeper to make sure we get notified only when the services we care about start or stop.

Step-by-Step: How to Trigger an Email Alert from a Windows Event that Includes the Event Details using Windows Server 2016

19 thoughts on “Step-by-Step: How to Trigger an Email Alert from a Windows Event that Includes the Event Details using Windows Server 2016

  1. Scott Russell says:

    Hello
    This is a good script. Question for you. Can you hide the credential so they are not shown in the script?

  2. cazzeggini says:

    Hi, thanks for the guide.
    I have a question.
    I would like to send an email when a scheduled activity generates an error.
    How can I do? Thanks

    1. daveberm says:

      Good question, I don’t know the answer. I’m assuming maybe the Scheduler throws an Error or Warning into the event log? If so, you can send an email that is triggered whenever that happens.

  3. Chris Montana says:

    Thanks for the info Dave, however how do we ensure the email is only sent once? I have the script flooding my mailbox with the emails once it recognizes the event ID once..is it possible to send an email only once after the event ID is logged?

    1. daveberm says:

      I’m not aware of an easy way to do that. This method is really just a poor man’s excuse for proper enterprise management system which would have features like that.

  4. Albert says:

    Followed this article along with the other “encrypt your credentials” to not have the password in plain text and it worked great for me. Used a Gmail account and Windows Server 2016. We did have to allow the security sign-ins on the first two attempts and allow unsecure apps from the Gmail account, after that it was successfull

  5. I have the script and also the task both running correctly manually, script using “Run as administrator” as the event is located in the Windows Security log. However on a Server 2019 the task will not trigger automatically and nothing appears in other logs (no DCOM error). Any thoughts on what else may be preventing the script from triggering properly?

  6. Utsav says:

    Very helpful blog, thank you for this first of all.

    Also I have a question, I am trying to automate this process by running a scheduled task to generate windows log (lets say at the end of every month) and email this when logs are generated.

    While doing this, I can create scheduled trigger to send an email and another one to trigger event of generating log. Can I merge this together? so it will generate log and email it after its done generating?

    Thank you in advance.

    1. daveberm says:

      I’m sure you can. Unfortunately I don’t have any great words of advice on how to write the script that accomplishes this process.

  7. ok so we have a system in our company; we post invoices after the end of the day and sometimes it could be all the way till after 9:00pm but the event managers sends invoices at 8:00pm so people do not get invoices till the next day or sometimes they wont send. Can there be a time change on event manager so that we can post invoices late and send later than 8pm?

    1. daveberm says:

      Good question. I think you would have to script something that looks for the invoice and then sleeps for 5 minutes if the invoice is not there. Put that in a do while loop until the invoice arrives and is sent. It’s beyond my expertise, but that might be where I start. Or maybe it is just easier to schedule a second event for later in the evening that mails the invoices again in case there were some late arriving invoices?

  8. appspi says:

    What’s the best way to troubleshoot this? I have everything setup correctly (afaik) but am not seeing any emails for real (or fake) Event Log events yet.

    1. appspi says:

      Still up for a reply but just FYI I got this working as described above – was a spam/port issue blocking me. BTW thanks for this post – very helpful!

  9. appspi says:

    Sorry to spam – I thought I was set here but all my emails include details from the same event – and an event that doesn’t match my ID filter (ID 16 is what I get vs. 0 or 1000 which I specified in my event filter). This is what every single email looks like – any ideas what I’ve done wrong/forgotten?

    EventID: 16
    Source: Microsoft-Windows-Kernel-General
    MachineName: MYMACHINE.situational.io
    Message: The access history in hive \??\C:\Windows\System32\SMI\Store\Machine\SCHEMA.DAT was cleared updating 1 keys and creating 1 modified pages.

    1. daveberm says:

      It looks like maybe you didn’t edit the script to account for your specific events? The example script references $EventId = 16,20,23,150,219,220. You would want to change that to $EventId = 0,1000

      1. appspi says:

        Thank you! Yes once I set it to 1000 it worked (0,1000 did not for some reason).

        I almost have this working but one (last?) thing is my body has a bunch of %n items in it – like the below. Is this normal/unavoidable or possible to get these variable to show up correctly? Here’s my full ps1 script as of now btw: https://gist.github.com/2a7e3961cdc09f5edd5d185c8c68d4fb

        version: %2, time stamp: 0x%3 Faulting module name: %4, version: %5, time stamp: 0x%6 Exception code: 0x%7 Fault offset: 0x%8 Faulting process id: 0x%9 Faulting application start time: 0x%10 Faulting application path: %11 Faulting module path: %12 Report Id: %13 Faulting package full name: %14 Faulting package-relative application ID: %15

Leave a Reply to daveberm Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s