Tracking and auditing changes to passwords in an Active Directory (AD) domain are crucial to maintaining a secure environment and heading off bad actors early. Thankfully, AD offers the information necessary to track these changes, despite being difficult to parse and understand at times. LAPS is a great example of this. Show In this article, you’re going to learn how to enable Active Directory auditing of passwords, how to filter events in the Event Viewer and use PowerShell to more easily audit the results with a script.
PrerequisitesIf you’d like to follow along with this tutorial, please be sure you have the following:
Enable Group Policy for Active Directory AuditingThe necessary auditing information you need to audit AD password changes is stored on domain controllers (DC), but the domain controller in the Primary Domain Controller (PDC) emulator role will ultimately process the request. But, by default, the necessary auditing isn’t enabled on DCs. Let’s change that.
To enable password change auditing, create a new group policy object (GPO). This GPO will be created and linked to the entire domain.
On your domain-joined workstation, create a GPO that forces DCs to begin auditing password changes:
2. Click on Create a GPO in this domain, and Link it here… and give the policy a name. This tutorial’s example will use the name Active Directory Password Auditing. 3. Once the policy has been created, right-click it, and choose Edit to open the Group Policy Management Editor. 4. Navigate to Computer Configuration → Policies → Windows Settings → Security Settings → Local Policies → Audit Policy → Audit account management. 5. Next, double-click on the Audit Account Management policy setting and check the checkbox Define these policy settings while ensuring both the Success and Failure checkboxes are checked. By doing so, successful and unsuccessful password attempts will be logged. 6. Click OK to close and exit the editor. 7. Open up a Remote Desktop (RDP) client and connect to the domain controller running the PDC emulator (PDCe) AD role.
8. On the PDCe DC, open a command prompt or PowerShell console and run gpupdate to force a group policy update.
Once the configuration changes have been made and group policy updated, you now have auditing events turned on and logging for account management. Read on to discover how to interpret these events. Deciphering Account Management Event LoggingThe category of audit events password changes fall under is called Account Management events. These events record information such as password change events and user account lockouts. Account Management audit events are logged as Windows events in the Security event log of a machine that has the auditing enabled. On your domain-joined machine:
2. Right-click on Event Viewer (Local) and select Connect to Another Computer…. 3. Provide the name of the DC running the PDCe role in the Another computer: box and click OK to connect Event Viewer to the DC’s event source. 4. Expand the Windows Logs item and click on Security. This will bring you to the Security log as shown below. Inside of the security log, you’ll find various events with a source of Microsoft Windows security auditing and User Account Management task categories as shown in the filtered view below. Each Windows event has a unique ID that represents the type of event. Though there are several event IDs that the Microsoft Windows security auditing source contains, the primary event IDs that you should be interested in for password changes (and user lockouts) are:
You’ll see a lot of events in the Security log so you’ll need to create an apply some filters to narrow down only password changes. Filtering on Password Change EventsWithin the Event Viewer, you can create a filter. A filter is a way to limit the number of events that show up and is mandatory when combing through the Windows Security event log. To create this filter in the Event Viewer:
2. In the Filter Current Log dialog box, create a filter to only find password change events using the following criteria and click on OK.
When you’re complete, your Filter Current Log screen should look like below. By filtering the Event Viewer, on the domain controller, to just the important event IDs a targeted list of events that have occurred specific to password and password changes are shown below. Voila! You now have all of the password change (and user lockout) events that have occurred in your domain since you’ve linked the GPO created earlier! Find Audit Events with PowerShellEven though you can use the Windows Event Viewer connected to the DC’s Security event log sometimes you need a faster approach. Perhaps you have some automation built in the background or would like to automatically monitor this event log. In this case, you should use PowerShell. Using PowerShell allows you to perform the exact same function all within a single script. With a script, you won’t have to connect to DCs, create filters manually and manually parse through events. To find important auditing events with PowerShell, use the Get-WinEvent cmdlet. This cmdlet queries a local or remote event log and returns all events. It also has support for filters too just as the Event Viewer does. If you’ve already built a filter with Event Viewer, you can even, in fact, share that same filter with PowerShell! Since PowerShell can use the same filter as the Event Viewer, let’s save some time and extract that filter and use it with PowerShell’s Get-WinEvent cmdlet. While still ensuring you’re still connected to the DC with Event Viewer:
4. Open up a PowerShell console and paste in the following code snippet. You can see the FilterXPath parameter value is the exact same text extracted from the Event Viewer filter above. Get-WinEvent -ComputereName <YOUR DC> -LogName 'Security' -FilterXPath "*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and Task = 13824 and (EventID=4723 or EventID=4724 or EventID=4740 or EventID=4767)]]" When you run Get-WinEvent, you should see all of the same events you saw in the Event Viewer earlier as shown in the following screenshot. You’ve now found all password change and user lockout events with PowerShell! Buiding a Password Change Auditing ToolYou’ve seen how to use PowerShell’s Get-WinEvent cmdlet to audit AD events. If you plan to do this often, it’s always a good idea to use a reusable tool to use in other scripts or automation routines. In this section, let’s build a PowerShell function called Get-ADPasswordEvent. This function will explore many techniques that can help you retrieve just the information that you want without all the additional properties that you get with Get-WinEvent. To not bore you with all of the details, you can see a complete function already built for you below. This function performs a few different tasks:
You can find more granular details in the code comments. Function Get-ADPasswordEvent { [CmdletBinding()] Param( [Parameter(Position=0)] [System.Collections.Generic.List[Int]]$EventID = @(4723,4724,4740,4767), [Parameter(Position=1)] [Int]$Hours, [Parameter(Position=2)] [ValidateSet("Success","Failure")] [System.Collections.Generic.List[String]]$EventType = @("Success","Failure"), [Parameter(Position=3)] [string]$ComputerName ) Process { # The event type filter values are from the Audit Success and Audit Failure in the Keywords section of the Event Viewer filter. If ($EventType -Contains "Success" -And $EventType -Contains "Failure") { $EventTypeFilter = " and (band(Keywords,13510798882111488))" } ElseIF ($EventType -Contains "Success") { $EventTypeFilter = " and (band(Keywords,9007199254740992))" } Else { $EventTypeFilter = " and (band(Keywords,4503599627370496))" } # We construct a filter to pass to -FilterXPath. Hours should be returned in milliseconds and we use Join-String to properly format the EventID combinations. $Filter = "*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and Task = 13824{0}{1}{2}]]" -F (($Hours) ? " and TimeCreated[timediff(@SystemTime) <= $((New-TimeSpan -Hours $Hours).TotalMilliseconds)]" : $Null), (($EventId) ? ($EventId | Join-String -OutputPrefix " and (" -FormatString 'EventID={0}' -Separator ' or ' -OutputSuffix ")") : $Null), $EventTypeFilter Write-Verbose $Filter $Events = Get-WinEvent -ComputerName $ComputerName -LogName 'Security' -FilterXPath $Filter # For the Password Change and Reset ID's we format the Details to be more readable and show what is going on regarding the target (account being changed) and the subject (who did the changing). $Events | ForEach-Object { $Event = $_ Switch ($Event.ID) { 4723 { $Description = "Account Password Change Attempt" $Details = [PSCustomObject]@{ "TargetAccount" = ("{0}\{1}" -F ($Event.Properties)[1].Value, ($Event.Properties)[0].Value) "TargetSID" = ($Event.Properties)[2].Value "SubjectAccount" = ("{0}\{1}" -F ($Event.Properties)[5].Value, ($Event.Properties)[4].Value) "SubjectSID" = ($Event.Properties)[3].Value } Break } 4724 { $Description = "Account Password Reset Attempt" $Details = [PSCustomObject]@{ "TargetAccount" = ("{0}\{1}" -F ($Event.Properties)[1].Value, ($Event.Properties)[0].Value) "TargetSID" = ($Event.Properties)[2].Value "SubjectAccount" = ("{0}\{1}" -F ($Event.Properties)[5].Value, ($Event.Properties)[4].Value) "SubjectSID" = ($Event.Properties)[3].Value } Break } 4740 { $Description = "Account Locked Out" $Details = $Event.Message Break } 4767 { $Description = "Account Unlocked" $Details = $Event.Message Break } Default { $Description = $Null $Details = $Event.Message Break } } # Finally let's output our custom object that shows the event information in a more readable format. [PSCustomObject]@{ "TimeCreated" = (Get-Date $_.TimeCreated) "ID" = $_.ID "Description" = $Description "EventType" = (($_.KeywordsDisplayNames -EQ 'Audit Success') ? "Success" : "Failure") "Details" = $Details } } } } Once created, drop this function into a PowerShell console and run it with no parameters. Shown below is running Get-ADPasswordEvent. You can see that the function returns many success and failure events for password reset attempts.
Implementing Better Password Auditing SolutionsWhether you’re using the Event Viewer or PowerShell, you have to jump through a few different hoops to find AD auditing events. The native tools and abilities of Active Directory could certainly be expanded upon, and for that, third-party tools such as Specops Password Auditor can help. Specops’ Password Auditor tool not only can find these events, but it can also create in-depth reports that include changes, expired passwords, blank passwords, and more. Specops Password Auditor can fill in the missing gaps for Active Directory password auditing. |