Audit Logon Successes & Failures on All Domain Controllers


In a realistic situation, InfoSec would notify DBAdmins and SysAdmins of failed logon alerts from certain service accounts. When using Windows to check the events, this would be a typical log item.


Since the event log on the Database Server only shows failed logins on itself, it is necessary to check domain controller logs using the commands shown below.

# Coding aspects...

# Run Locally on Each DC
GET-EVENTLOG -Logname Security | where { $_.EntryType -eq 'FailureAudit' }

# Initiate from a Jump Box with a single DCNAME
GET-EVENTLOG -Logname Security -Computername DCNAME | where { $_.EntryType -eq 'FailureAudit' }

# Initiate from a Jump Box with access to All DCs
Import-Module ActiveDirectory
#$readWriteDCs=Get-ADDomainController -Filter * | Where-Object {$_.IsReadOnly -ne "False"} | Select Name
$allDCs=Get-ADDomainController -Filter * | Where-Object {$_.IsReadOnly -ne "False"} | Select Name
$allDCs.Name | ForEach-Object -Process {GET-EVENTLOG -Logname Security -Computername $_ | where { $_.EntryType -eq 'FailureAudit' } | export-csv "C:\Reports\$_`-LogonFailures.csv"}

The audit logs would only be available if the Group Policy (GP) Audit Logon has been set to capture Success and Failure events. Here are the steps to enable this using GP.

Locate the Default Domain Controllers Policy > Edit > navigate to Computer Configuration – Windows Settings – Advanced Audit Policy Configuration – Logon/Logoff > double-click on Audit Logon > set value = Success and Failures

Other Considerations:

1. How many events will be generated if this is turned on?

This extra logging will persist on all DCs as long as the policy is applied. The impact can be estimated using this formular:

Extra events per day = Sum((Number of Users x probability of users logon failures per user per day) +(number of service accounts x probability per account per day) + (number of computer accounts x probability per computer per day))

This would be a guess for a company of 1000 employees: ((1000 x .1) + (300 x .0001) + (1500 x 0.00001)) = 100.045 extra events will be generated per day.

2. How much disk space will this take for the extra logging?

Disk storage = Extra events per day x average size of each failure log

How about this guess: ((1000 x .01) + (300 x .0001) + (1500 x 0.00001)) x 200 bytes = 20,009 bytes per day ~ 600,270 bytes per 30-day extra logging (586.20 MBs of storage per month)

– Returns System.Diagnostics.Eventing.Reader.EventLogRecord.
– Uses the EventLog engine on the remote machine to filter the logs prior to sending results over the wire. This potentially reduces the amount of data to be transmitted on smaller logs.
– Can be parsed into XMLs and accessed on-the-fly:
$eventxml = $event.ToXML()
– Note: -FilterHashTable parameter only works with Windows 7 & Windows 2008R2. It will not work with Windows 2008. On these incompatible systems, use –FilterXML instead
– Syntax:

Get-EventLog: returns System.Diagnostics.EventLogEntry
– Runs approximately 2x faster than Get-WinEvent to retrieve Security logs for Audit Failures
– Example: GET-EVENTLOG -Logname Security -Computername $Server | Where { (“FailureAudit” -eq $_.EntryType) }

# Script to collect all failed logon attempts as recorded on all DCs

Import-Module ActiveDirectory;
#$allDCs=Get-ADDomainController -Filter * | Where-Object {$_.IsReadOnly -ne "False"} | Select Name
$allDCs=Get-ADDomainController -Filter * | Select Name
$allDCs.Name | ForEach-Object -Process {GET-EVENTLOG -Logname Security -Computername $_ | where { $_.EntryType -eq 'FailureAudit' } | export-csv "C:\Reports\$_`-LogonFailures.csv"}
This would happen if one tries to open the file while it's being generated:
export-csv : The process cannot access the file because another process has locked a portion of the file.
At line:1 char:135
+ ... -eq 'FailureAudit' } | export-csv "C:\Reports\$_`-LogonFailures.csv"}
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Export-Csv], IOException
+ FullyQualifiedErrorId : System.IO.IOException,Microsoft.PowerShell.Commands.ExportCsvCommand
# Script to audit successful logons of a particular account in the past 7 days

Import-Module ActiveDirectory;
$allDCs=Get-ADDomainController -Filter * | Select Name
$allDCs | ForEach-Object -Process {GET-EVENTLOG -Logname Security -Computername $_.Name -After (Get-Date).AddDays(-7) | where { $_.EntryType -eq 'SuccessAudit'} | where { $_.TargetUserName -eq 'svc_oitwflow' } }

Leave a Reply

Your email address will not be published. Required fields are marked *