<

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x

Event Log Notification via PowerShell and Task Scheduler

Published on
30,010 Points
18,010 Views
5 Endorsements
Last Modified:
Awarded
Editor's Choice
With the release of Task Scheduler 2.0 (which shipped with Vista and Server 2008) Microsoft has upped the ante with an exciting list of changes.  Starting with Windows 7, Task Scheduler 2.0 now uses the unified scheduling engine provided by the underlying OS, the ability to reject starting tasks in Remote Apps Integrated Locally (RAIL) sessions, as well as task security hardening and a slew of API changes.  

Diving deeper into the API changes, the new Triggers and Actions have now become a staple of the IT Administrator and Support Teams, in an effort to standardize and automate their workflow.  Building upon Microsoft's Task Scheduler foundation of calendar and event-based triggers, we are now able to drill down into specific Actions and Triggers and use them to our advantage in a very simple and straightforward approach, while utilizing PowerShell to fill in any remaining gaps, such as in the email reporting.

In an undersized or underfunded environment, investigating and finding solutions to some events can be prove to be a nightmare.  While larger environments may utilize tools such as Microsoft's System Center Operations Management or other similar tools, those smaller organizations are left to rely on Open Source or custom tool sets.

Truth of the matter is, sometimes you just need a quick and dirty method of notification in the event (pun intended) that something pops up in a log.  Utilizing a simple to use and customize PowerShell script, we can add in the resources of the Event Viewer and the Task Scheduler to send a notification email to a specified user or help-desk when an Event is logged.

The first step is find your Event ID and then customize the following PowerShell script.

Navigate to the event in Event Viewer (eventvwr) under Windows\system32\ or by clicking Start and typing Event.  Once you have found your event in the Event Viewer that you would like to be notified about, record the Event ID as indicated in the following image.



#PowerShell must run with elevated permissions:
If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))

{   
$arguments = "& '" + $myinvocation.mycommand.definition + "'"
Start-Process powershell -Verb runAs -ArgumentList $arguments
Break
}
#Powershell is now elevated

$Event = Get-EventLog -LogName LOG_NAME -InstanceId EVENT_ID -Newest 1
$MailBody= $Event.Message + "`r`n`t" + $Event.TimeGenerated

$MailSubject= "EMAIL_SUBJECT"
$SmtpClient = New-Object system.net.mail.smtpClient
$SmtpClient.host = "SMTP.DOMAIN.COM"
$MailMessage = New-Object system.net.mail.mailmessage
$MailMessage.from = "FROM_EMAIL@DOMAIN.COM["
$MailMessage.To.add("TO_EMAIL@DOMAIN.COM[")
$MailMessage.IsBodyHtml = 0
$MailMessage.Subject = $MailSubject
$MailMessage.Body = $MailBody
$SmtpClient.Send($MailMessage)

Open in new window


For this example script set, I will be working with a User Lockout Event, which has an Event ID of 4740.  Using the script template above and a basic text editor like Notepad or my choice, Notepad++, we can replace the following values:

LOG_NAME - Application, Security or System.
EVENT_ID - Numerical Event Log ID.
EMAIL_SUBJECT - Subject of the Email you receive.
SMTP.DOMAIN.COM - SMTP address of your mail server.  You can also use a free email service such as Google's GMAIL with the following settings as described here.here.
FROM_EMAIL@DOMAIN.COM - Sender's email
TO_EMAIL@DOMAIN.COM - Who the email is sent to.

and get our final script:

#PowerShell must run with elevated permissions:
If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))

{   
$arguments = "& '" + $myinvocation.mycommand.definition + "'"
Start-Process powershell -Verb runAs -ArgumentList $arguments
Break
}
#Powershell is now elevated

$Event = Get-EventLog -LogName System -InstanceId 4740 -Newest 1
$MailBody= $Event.Message + "`r`n`t" + $Event.TimeGenerated

$MailSubject= "User Lockout Notification"
$SmtpClient = New-Object system.net.mail.smtpClient
$SmtpClient.host = "mail.mymailsite.com"
$MailMessage = New-Object system.net.mail.mailmessage
$MailMessage.from = "admin@mymailsite.com"
$MailMessage.To.add("admin@mymailsite.com")
$MailMessage.IsBodyHtml = 0
$MailMessage.Subject = $MailSubject
$MailMessage.Body = $MailBody
$SmtpClient.Send($MailMessage)

Open in new window


Now that the script is finished, save down to a directory you can remember, such as \\location\scripts, as a PowerShell shell script (.ps1).  Once the file is saved, we can set up our trigger-

Navigate back to the event in the Event Viewer, highlight the event by single-clicking, and then using the right-click menu, select 'Attach Task To This Event' as illustrated below.



In the New popup window, fill out the Name of the Task or optionally leave as-is, and add a description.  I highly encourage that all Tasks have at least a very basic description.  In the event of multiple personnel, you do not want them to delete your Task, not knowing what it is used for.



When you advance to the next screen using the 'Next >' button, you can verify the trigger with the shown Log, Source and Event ID Fields.  



Advance to the next screen using the 'Next >' button and then choose 'Start a program'*, and then hit 'Next >' again.  On the next screen, you will need to select the 'Browse...' button and navigate to, and then select your script that you saved earlier.  



Select the 'Next >' button to continue on to the Finish screen.

Optionally, you can use a command that you would normally type into the 'run' dialogue to execute a script, including any switches/arguments.  When you select 'Next >' to advance to the Finish Screen, the Task Wizard will automatically recognize and parse the command and the switches/arguments for you.

On the Finish screen, you will be able to view the Summary of the Task that you have created.  



Once you have verified the Summary, select 'Finish'.

Now that your logs are now being monitored by your Task Scheduler, the following actions will take place:

1. Task Scheduler monitors the Event Viewer for the specified Event
2. Once the specified events occurs, the Task scheduler will call up the PowerShell script.
3. The .ps1 file will open PowerShell, parse the Event Logs for the specified event and append the output to an email.
4. An email is sent to the specified address with the appended Event Log information.

Using this method, hopefully you will now go out and take any of the Windows Event ID's that you would like to monitor, and set up notification features or a variety of other actions based on your specific needs.

--------------------------

For more information on Microsoft's System Administration Tools, please visit:  Windows Dev Center - System Administration

*   Using the 'Attach Task to this Event' method you do have the option to send an email upon the Event occurring; however, the email will not contain any relevant information for business level purposes (e.g. UserName or Caller as used in the User lockout example).
5
Comment
  • 4
  • 4
  • 2
  • +3
13 Comments
LVL 74

Expert Comment

by:Qlemo
Note that you can use Send-MailMessage now, which allows for providing all necessary data when calling instead of having to deal with two different objects. Lines 12-23 of your script would look like this:
Send-MailMessage -SmtpServer mail.mymailsite.com `
  -From admin@mymailsite.com  -To admin@mymailsite.com `
  -Subject  "User Lockout Notification" `
  -Body $Event.Message + "`r`n`t" + $Event.TimeGenerated

Open in new window

0
LVL 18

Author Comment

by:Steven Harris
Hi Qlemo,

You are absolutely correct about the Send-MailMessage cmdlet.  I hope your comment may spur an idea for another user.

Thank you for the read and suggestion!
0

Expert Comment

by:lineonecorp
Thanks for all the work here. I have tried to absorb both code chunks - substituting per Qlemo his lines to replace 12-23 -   and I would like to see if I have the idea right.

What I am trying to do is get an email sent to a g-mail account - xyz@gmail.com - when Event 32315 happens.

Here is what I have:

+++++++++

#PowerShell must run with elevated permissions:
If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole

([Security.Principal.WindowsBuiltInRole] "Administrator"))

{  
$arguments = "& '" + $myinvocation.mycommand.definition + "'"
Start-Process powershell -Verb runAs -ArgumentList $arguments
Break
}
#Powershell is now elevated

$Event = Get-EventLog -LogName System -InstanceId 32315 -Newest 1
Send-MailMessage -SmtpServer smtp.gmail.com
  -From xyz@gmailcom  -To xyz@gmailcom `
  -Subject  "32315 notification" `
  -Body $Event.Message + "`r`n`t" + $Event.TimeGenerated

++++++++++

Questions:

ThinkSpaceSolutions had a link for gmail setting and in it there was the following:

smtp.gmail.com (use authentication)
Use Authentication: Yes
Use STARTTLS: Yes (some clients call this SSL)
Port: 465 or 587

Am I supposed to somehow encode that in the script above? And how would I do that?

What about my gmail password - where does that go?

And just to be doubly sure at the end of this when event 32315 takes place I will get notified via email - it's not a matter that I will get alerted after the fact that the event happened.

If this should be a post instead of a comment let me know and I will do so.

Thanks in advance.
0
Problems using Powershell and Active Directory?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

LVL 74

Expert Comment

by:Qlemo
You will have to add -UseSSL -Credential $cred with $cred being valid credentials for GMail.
0

Expert Comment

by:lineonecorp
Thanks for the quick reply.

So the line I would need assuming the password was password would read:

Send-MailMessage -SmtpServer smtp.gmail.com -UseSSL -Credential password

or

Send-MailMessage -SmtpServer smtp.gmail.com -UseSSL -Credential $password


And just to be sure there is a space between .com and -UseSSL

Also if I want further modifications e.g. the ability to monitor more than one event should I post that instead so you get some points?
0
LVL 74

Expert Comment

by:Qlemo
There are several ways to create a PSCredential object, which isn't the plain text password - but that is beyond this article, and so you should indeed post an own question for your requirements (but don't forget to link back to this article for reference).

Anyway, for multiple event IDs to monitor you can go the easy way and just repeat above for each ID individually. But then it would be better to just call the same script with parameters instead of hard-coding the event IDs.
0

Expert Comment

by:lineonecorp
Thanks. I will post as you suggest.

However, just to finish this, which of these is correct?
+++++++++++
So the line I would need assuming the password was password would read:

Send-MailMessage -SmtpServer smtp.gmail.com -UseSSL -Credential password

or

Send-MailMessage -SmtpServer smtp.gmail.com -UseSSL -Credential $password


And just to be sure there is a space between .com and -UseSSL
+++++++++++
0
LVL 74

Expert Comment

by:Qlemo
Neither. PSCredential objects contain the user and the password, with the password encrypted. If you run $cred = Get-Credentials, and then examine $cred, you'll see what I mean.
0
LVL 18

Author Comment

by:Steven Harris
Sorry for the delay, I haven't been receiving email updates from this Article...

To pick up with Qlemo's comments:

1)  This is beyond the scope of this article, so should be moved to a Question.  Link-backs to this article are especially helpful for other Experts as well to help identify the source code and any modifications you are trying to make.

2)  To expand on the $cred example from above, the correct syntax is 'Get-Credential' which retrieves a credential object based upon a username and password.  Instead of storing the credentials as a text-string, the 'Get-Credential' line will prompt you for the information via a control box and then store the password as 'System.Security.SecureString'.

$cred = Get-Credential

echo $cred

Open in new window

0
 

Administrative Comment

by:lherrou
ThinkSpaceSolutions,

Experts Exchange's highest accolade for articles is reserved for only the best articles on the site.

Congratulations. The EE editorial team has voted on your article, and it has been deemed worthy of "Editor's Choice."

LHerrou
Experts Exchange Editor
0
LVL 19

Expert Comment

by:Kash
I have created a small event log viewer program which takes some arguments and then displays the log from the remote computer.
Its nothing off advanced level but may benefits someone and can be accessed here >> http://kash-knows.co.uk/?p=56
http://kash-knows.co.uk/?p=64
0

Expert Comment

by:lineonecorp
Thanks for the additional work.
0
LVL 1

Expert Comment

by:Hal-itosis
Hi,
I'm trying to get this script working with ForwardedEvents log but Get-EventLog is not able to view it.
Has anyone got a similar script that uses Get-WinEvent to read events in ForwardedEvents log ?
0

Featured Post

Challenges in Government Cyber Security

Has cyber security been a challenge in your government organization? Are you looking to improve your government's network security? Learn more about how to improve your government organization's security by viewing our on-demand webinar!

Join & Write a Comment

Loops Section Overview
Did you know PowerShell can save you time with SaaS platforms? Simply leverage RESTfulAPIs to build your own PowerShell modules. These will kill repetitive tickets and tabs, using the command Invoke-RestMethod. Tune into this webinar to learn how…

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month