Event Trigger - phbits/WebsiteFailedLogins GitHub Wiki

Taking action on an alert using Event Triggers is used when alerts are written to the Windows Event Log. This can useful for stand-alone systems or environments leveraging Windows Event Collection (WEC).

Example

[Alert]
Method = WinEvent
[Alert]
Method = WinEvent,Smtp

Overview

Setting this up is a two-part process that will be explained further below. Note that this process will need to be completed twice. Once for FailedLoginsPerIPEventId and again for TotalFailedLoginsEventId.

  1. Setup Event Trigger
  2. Create Action Script

Event Trigger

The following PowerShell snippet will create an Event Trigger. The same can be achieved by using the command-line utility SCHTASKS or via the User Interface (UI) taskschd.msc.

Information needed to complete this script include:

  1. Name of script this trigger should call.
  2. User account this trigger should runas. This account will also be used to run the script mentioned above.
  3. Working directory.
  4. WinEvent settings from WebsiteFailedLogins configuration file.
# ExecutionPolicy set to Unrestricted should only be used for testing.
# Specify the name of the script by replacing Application-EventID10.ps1
# update working directory to reflect your environment
$Action = New-ScheduledTaskAction -Execute 'C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe' `
                                  -Argument -NoLogo -NoProfile -NonInteractive -WindowStyle Hidden `
                                  -File .\Application-EventID10.ps1 -RecordID $(eventRecordID) `
                                  -ExecutionPolicy Unrestricted' `
                                  -WorkingDirectory 'C:\WebsiteFailedLogins\'

# Specify the user account to run this task and the script it calls. 
$Principal = New-ScheduledTaskPrincipal -UserId 'NT AUTHORITY\SYSTEM' -LogonType ServiceAccount
 
$Settings = New-ScheduledTaskSettingsSet -DisallowDemandStart -Compatibility Win8 -Hidden -WakeToRun `
                                         -RunOnlyIfNetworkAvailable -AllowStartIfOnBatteries

$Settings.RunOnlyIfIdle = $FALSE
$Settings.ExecutionTimeLimit = 'PT5M'
$Settings.StartWhenAvailable = $TRUE
$Settings.StopIfGoingOnBatteries = $FALSE
$Settings.DisallowStartOnRemoteAppSession = $FALSE
$Settings.DisallowStartIfOnBatteries = $FALSE
 
$cimTriggerClass = Get-CimClass -ClassName MSFT_TaskEventTrigger `
                                -Namespace Root/Microsoft/Windows/TaskScheduler:MSFT_TaskEventTrigger
 
$Trigger = New-CimInstance -CimClass $cimTriggerClass -ClientOnly

# update the following XPath query with values used in the WebsiteFailedLogins configuration file 
$Trigger.Subscription = "<QueryList><Query Id=`"0`" Path=`"Application`"><Select Path=`"Application`">*[System[Provider[@Name='WebsiteFailedLogins'] and (EventID=10)]]</Select></Query></QueryList>"

$Trigger.ExecutionTimeLimit = 'PT5M'
$Trigger.Enabled = $TRUE
 
# Setting ValueQueries enables RecordID to be passed to the script
$Trigger.ValueQueries = [CimInstance[]] $(Get-CimClass -ClassName MSFT_TaskNamedValue -Namespace Root/Microsoft/Windows/TaskScheduler:MSFT_TaskNamedValue)
 
$Trigger.ValueQueries[0].Name = 'eventRecordID'
$Trigger.ValueQueries[0].Value = 'Event/System/EventRecordID'

# Update as desired: TaskName, Description, TaskPath
Register-ScheduledTask -TaskName 'ApplicationEventID10-W3SVC1' `
                       -Description 'Run script on Application Event 10' `
                       -TaskPath '\WebsiteFailedLogins\' `
                       -Action $Action `
                       -Trigger $Trigger `
                       -Settings $Settings `
                       -Principal $Principal

Action Script

param([int]$RecordID)

# If writing to an Event Log other than Application
# update the following $xmlQuery
$xmlQuery = @"
<QueryList>
 <Query Id="0" Path="Application">
  <Select Path="Application">*
   [System[(EventRecordID=$($RecordID))]]
  </Select>
 </Query>
</QueryList>
"@
 
$alertEvent = Get-WinEvent -FilterXml $xmlQuery

# uncomment if DataType = xml
# $alertData = [System.Management.Automation.PSSerializer]::Deserialize($alertEvent.Message)

# uncomment if DataType = json
# $alertData = $alertEvent.Message | ConvertFrom-Json

<#
# following is how to access the data.
# UrlPath only available when Authentication=Forms
$alertData.ClientIP       # 10.0.0.11
$alertData.FailedLogins   # 20
$alertData.Sitename       # W3SVC1
$alertData.IISLogPath     # C:\inetpub\logs\LogFiles\W3SVC\
$alertData.Authentication # Forms
$alertData.HttpResponse   # 401
$alertData.UrlPath        # /login.aspx
$alertData.Start          # 2021-01-26T18:17:51Z
# End must be used with quotes due to "~"
$alertData.'End~'         # 2021-01-26T18:22:51Z
#>

# do something with $alertData here
⚠️ **GitHub.com Fallback** ⚠️