0

I am having below script:

$pattern = 'Unable to authenticate user!'
$events = Get-WinEvent -ea SilentlyContinue `
-ProviderName "Windows DB Controller - Task Manager Service"|
Where-Object { $_.TimeCreated -gt [datetime]::today -and $_.Message -match $pattern }
$events   >> D:\Error.txt 

if ($events) {
Send-MailMessage -SmtpServer smtp.domain.com -From No-reply@domain.com -To sunny@domain.com -Subject 'Error found in log' -Body $events
}

I had scheduled it to run on every 10 mins and purposely ,I wanted to achieve following point using above script:

Search the specified error message in the event viewer log only for current-date and as soon as the error message encountered send a email notification to me but didn't want to receive email notification for the error message which appreared today and for which I had already been notified (I mean , wanted to receive error-notification only once for a specific time of current day).

But problem I am facing here is: Getting multiple notifications for same error message for which already being notified.

I hope I am clear enough to put my exact problem.

Could you please help me out, how to resolve this problem ?

Sunny
  • 7,812
  • 10
  • 34
  • 48

3 Answers3

1

If you are running the script every 10 minutes, I would change the condition on the Where-Object so instead of getting all of the events that are "today"; I would change it to get only the events that happened in the last 10 minutes. i.e. the code becomes:

Where-Object { $_.TimeCreated -gt [datetime]::now.AddMinutes(-10) -and $_.Message -match $pattern }
HAL9256
  • 12,384
  • 1
  • 34
  • 46
  • @HAL..+1. This seems to be working. I'll test it on my system and will let you know the result. – Sunny Jan 13 '14 at 14:55
  • This only masks the problem. If your script takes 2 min to run, and you only get the last 10 minutes, and you only run the script every 10 min, you may be missing 2 min of events. – Jean-Claude DuBois Feb 26 '22 at 01:24
1

Have a look at this thread:

Powershell - Tail Windows Event Log? Is it possible?

It's on tailing an event log, but the same method should work for what you're tyring to do. Just save the last index number to a file between runs.

Community
  • 1
  • 1
mjolinor
  • 66,130
  • 7
  • 114
  • 135
  • @mjolinor..but that code snippet is generalized and that's why very slow and moreover that doesn't have constraint set on error message, provider name and time. how that fulfill my requirements ? – Sunny Jan 13 '14 at 14:38
  • It should be considerably faster than using -After, which is going to make it read the entire log, and it should be consrained to only log entries you haven't read yet. – mjolinor Jan 13 '14 at 15:03
  • I'm sorry but still i am not getting , because under `-LogName System`I've no concern with reading newest log entries. I am only interested in specific error messages coming from a fixed Provider in a particular day without duplication of a appeared message. – Sunny Jan 13 '14 at 15:15
  • The point is to use the event indexes to determine what's been read, and how many events you need to read to get back to the last point in the log where you've read the events. You calculate the number of log events to read from the index number of the newest event in the log and the saved index number of the newest event from the last run, then read than many entries with -MaxEvents. – mjolinor Jan 13 '14 at 15:30
1

How about the following approach:

Register-WmiEvent -Query "select * from __InstanceCreationEvent where TargetInstance ISA 'Win32_NTLogEvent' and TargetInstance.SourceName = 'Windows DB Controller - Task Manager Service' and TargetInstance.Message LIKE '%Unable to authenticate user!%'" -SourceIdentifier "MyEventListener" -Action {
    #Your actions
    write-host "$($eventargs.NewEvent.TargetInstance.RecordNumber) at $($eventargs.NewEvent.TargetInstance.TimeGenerated)"
}

It uses WMI to subscribe to the event that occurs when an eventlog entry is generated with your criterias. The action itself will only return the new object(so no more duplicates). I've included a sample action to help you understand how to access the object. This method will give you live monitoring.

Inside the action, $eventargs.NewEvent.TargetInstance will give you the object which is an instance of win32_ntlogevent. To see properties of this class, check out TechNet or run the following command:

([wmiclass]'win32_ntlogevent').Properties | ft Name

To make the script run forever, just call your script with powershell -file script.ps1 -noexit or include a while($true) loop at the end of your script. (I'm not sure how the while-loop will affect resource usage longterm, you'd have to test).

Frode F.
  • 52,376
  • 9
  • 98
  • 114