Hunting Event Logs
Hunt-EventLog function monitors a specific Event log like Application, System or any other and triggers an action when a specific Event occurs. By default it looks for changes in the Event log every 30 seconds and searches the EventID; you can change this interval with -Interval paramaters. Hunt-EventLog echoes information in every interval which can be silenced with -Silent $true
Hunt-EventLog also can be called as a background job with -AsJob $true parameter. When you call Hunt-EventLog with -AsJob $true parameter it returns the Job object that is created for it; so you can assign it to a variable to return the output later. AsJob parameter works only if you copy the Hunt-EventLog.ps1 file under C:\ps\library\Hunt-EventLog.ps1. I will post another blog about how I'm using these scripts in my own environment
Here is the function code; as usual check the attachment to get it in ps1 format
function Hunt-EventLog
{
<#
.Synopsis
Searches for a specific EventID in Event Viewer and gives a specific response
.Description
This cmdlet loops until it finds the EventID that user enters and gives the response user wants
.Parameter EventID
Specifies EventID that is being search for
.Parameter LogName
Specifies the name of the event log. EventID will be searched in this log
.Parameter ScriptString
Specifies the action commands to run. Enclose the commands in double quotes ( " " ) to create a script string
.Parameter Interval
Specifies the wait interval between the executions of the function. The value of this parameter is second and default value is 30 seconds
.Parameter Silent
Specifies whether output to the screen is allowed or not
.Parameter AsJob
Creates a background job for the cmdlet and echoes the jobID
.Example
Hunt-EventLog -LogName Application -EventID 8225 -ScriptString "do something"
.Example
Hunt-EventLog -LogName Application -EventID 8225 -Interval 60
.Link
https://blogs.msdn.com/candede
.Notes
Author: Can Dedeoglu
#>
param
(
[Parameter(mandatory=$true,position=0)]
[string]$LogName
,
[Parameter(mandatory=$true,position=1)]
[string]$EventID
,
[Parameter(mandatory=$true)]
[string]$ScriptString
,
[Parameter(mandatory=$false)]
[int]$Interval = 30
,
[Parameter(mandatory=$false)]
[bool]$Silent = $false
,
[Parameter(mandatory=$false)]
[bool]$AsJob = $false
)
$startupLog = Get-EventLog $LogName -Newest 1
$startupTime = $startupLog.TimeGenerated
$startupIndex = $startupLog.Index
[bool]$logsCaptured = $false
function startControl([datetime]$time)
{
function writeConsole([int]$output)
{
if(!$Silent)
{
switch($output)
{
1
{
$(Get-Date).tostring("HHmmss") + ": Logs between Index " + ($newLogs[-1]).Index + "-" + ($newLogs[0]).Index + " has been scanned; there is no match"
}
2
{
(Get-Date).tostring("HHmmss") + ": sleeping " + $Interval + " seconds"
}
3
{
(Get-Date).tostring("HHmmss") + ": no new logs, last log Index was " + $currentIndex
}
}
}
}
$newLogs = @(Get-EventLog $LogName -After $time)
if(!$logsCaptured)
{
$currentIndex = $startupIndex
$currentTime = $startupTime
}
if($newLogs.count -gt 0)
{
$newTime = ($newLogs[-1]).TimeGenerated
$results = @($newLogs | ?{$_.InstanceId -eq $EventID})
if($results.count -gt 0)
{
Invoke-Command -ScriptBlock ([scriptblock]::Create($ScriptString))
}
else
{
writeConsole(1)
writeConsole(2)
$currentIndex = ($newLogs[0]).Index
$currentTime = ($newLogs[0]).TimeGenerated
$logsCaptured = $true
Start-Sleep -Seconds $Interval
startControl $newTime
}
}
else
{
writeConsole(3)
writeConsole(2)
Start-Sleep -Seconds $Interval
startControl $currentTime
}
}
if(!$AsJob)
{
startControl $startupTime
}
else
{
Start-Job -ScriptBlock ([scriptblock]::Create(". c:\ps\library\Hunt-EventLog.ps1; Hunt-EventLog -LogName $LogName -EventID $EventID -ScriptString `"$ScriptString`" -Interval $Interval -Silent `$$Silent"))
}
}
Cheers, CanD