Not all logon attempts with a bad password count against the account lockout threshold. Passwords that match one of the two most recent passwords in password history will not increment the badPwdCount. Nor will they update the badPasswordTime attribute of
the user. Because the lockoutObservationWindow attribute is the amount of time since the badPasswordTime was last updated, this affects how quickly badPwdCount is reset.
Several features of Active Directory account lockout are not well understood. For example, not all bad password attempts count
towards account lockout. And the lockoutObservationWindow attribute is not what many people think. It is not the amount of time during which the bad password attempts must occur. It is also not just the amount of time allowed between bad attempts without resetting
badPwdCount. Rather, it is the amount of time since the badPasswordTime attribute was last updated before the badPwdCount attribute resets. In group
policy this is called "Reset account lockout counter after" and is shown in minutes. This Wiki article explains some of the lesser known features of account lockout.
↑ Return to Top
Some of the Active Directory attributes relevant to account lockout are documented in the table below. Also included are the corresponding PowerShell
property name and the Group Policy Setting.
The first four attributes in the table only apply to the domain object in Active Directory. This is the default Domain Password and Account
Lockout Policy. Similar attributes apply to Password Setting Objects (PSO's). The corresponding PSO attribute names are the same, but start with
the string "msDS-". The only exception is the PSO attribute corresponding to pwdHistoryLength, which is msDS-PasswordHistoryLength. The last six attributes apply to users. The final two are not
replicated, so each
domain controller maintains its own values for each user.
Account lockout was straightforward in a domain at Windows 2000
domain functional level. When the number of bad password attempts reached the value of the lockoutThreshold attribute, the account was locked. All bad password attempts were forwarded to the DC
with the PDC Emulator role. The total count was maintained on that DC. The lockoutObservationWindow attribute specified the amount of
time since the badPasswordTime attribute was last updated before the badPwdCount attribute was reset.
Enhancements were introduced for domains at Windows Server 2003 functional level and above. When the bad password matches either of the two most recent entries in password history, the badPwdCount attribute is not incremented and the badPasswordTime attribute
is not updated. This means that normal users can make more attempts before they are locked out. Their bad password attempts are more likely to be passwords they recently used.
The meaning of the lockoutObservationWindow attribute is the same. But because badPasswordTime is not updated for every bad password attempt, it affects the number of attempts users are allowed in some cases. The badPwdCount is more likely to reset when
a user attempts with an old password.
This new feature is sometimes called password history n-2. The most recent previous password is referred as n-1. The next most recent is n-2. Not all authentication
types will take advantage of this new feature. Kerberos and NTLM
authentication protocols support password history n-2. These protocols are used when either a password or smart card is used for interactive logon. Other protocols, such as RADIUS
and PEAP, may or may not increment badPwdCount when a bad password is attempted. Some protocols do not forward bad password attempts to the PDC Emulator. That might explain why phone users can get locked out if the phone attempts repeatedly to authenticate
with a bad password.
In addition, the system can only know about the previous 2 passwords in history if pwdHistoryLength is at least 3. With that setting, the user can rotate through 3 passwords, so the previous 2 are retained in password history. If pwdHistoryLength is 2, the
user can alternate between two passwords. The only password attempt that will not increment badPwdCount in that case is the previous one. The system does not retain the second most recent password.
Tests were conducted to verify several features of account lockout in a domain at Windows Server 2003 or higher functional level. The relevant settings for these tests are documented in the following table.
The relevant group policy settings are shown in this image. Some of the values in the GUI are truncated to the nearest minutes or
days. For example, minimum password age was actually 13 minutes 20 seconds.
Two PowerShell version 1 scripts were developed to help with these tests. The first script finds all accounts with one or more bad password attempts on any domain controller in the domain. This script is linked here:
Find All Accounts with Bad Password Counts
The second script retrieves attribute values relative to bad password attempts for a specified account on every domain controller in the domain. The attributes are
sAMAccountName, pwdLastSet, lockoutTime, lastLogon, logonCount, badPwdCount, and badPasswordTime. The last four are not replicated. The script is linked here:
Troubleshoot Account Bad Password Attempts
For these tests the current password of the user was "Pas$00". The most recent password in password history was "Pas$01". The second most recent was "Pas$02", and so on. The fifth most recent password, "Pas$05" was not retained in password history because
pwdHistoryLength is 4.
In the table below, the first column, labeled "Elapsed", is the time in minutes and seconds since the badPasswordTime attribute was updated on a domain controller. "Client (DC)" shows the client computer used by the user when the logon was attempted, with
the name of the domain controller that the client is connected to in parentheses. This would be the value of the "LogonServer" environment variable on the client. The third column in the table is the password used in the logon attempt. Next in the table are
the results found on three domain controllers after the logon attempt. One DC was the LogonServer, where the logon request was handled. The other DC was not affected, but the DC that holds the PDC Emulator role, designated by "PDCe",
is always updated. For each of the three DCs, the column labeled "Count" is the value of the badPwdCount attribute for the user. The column labeled "Time" is the value of the badPasswordTime attribute on the DC.
The test results are documented below. Bad password attempts that increment badPwdCount and update badPasswordTime are highlighted in red. Bad password attempts that do not increment badPwdCount or update badPasswordTime are highlighted in orange. A successful
logon is highlighted in green.
Notice that the DC with the PDC Emulator role always has the latest information, even though in these tests it is never the DC that handles the logon attempt. Whenever a DC finds that a logon attempt has a bad password, it immediately contacts the PDC Emulator
to check if the password was recently changed. If the PDC Emulator replies that the password is still bad, it increments the value of badPwdCount and updates the value of badPasswordTime for that user on the PDC Emulator. In this way, these values on the PDCe
always reflect the true values for the user, unless the PDCe is not available. Any documentation that implies you must query all domain controllers in the domain and add the badPwdCount on each to get the true value is wrong on this point. The most up-to-date
values of badPasswordTime and badPwdCount should always be on the PDC Emulator.
The lockoutObservationWindow is 5 minutes for these tests. The first three bad password attempts in the table above cause the badPwdCount on DC01 to increment to 3. For the next three bad password attempts badPwdCount is not incremented because the passwords
are among the 2 most recent values in password history. By the time the next bad password is attempted that increments the count, almost 12 minutes has elapsed since badPasswordTime last updated. This exceeds the value of lockoutObservationWindow, so the count
is reset and badPwdCount is back to 1. After this several more bad password attempts increment badPwdCount to 3 and update badPasswordTime. The final password attempt on client "WS01" is a password among the 2 most recent in password history, so neither badPwdCount
nor badPasswordTime are updated.
Next, the bad password attempts switch to client "WS02", which is connected to "DC02". The first logon attempt on this client is again a password among the 2 most recent in history, so nothing is updated. But the next two attempts now increment badPwdCount
and update badPasswordTime on "DC02". After this, the count on "DC01" is 3 and the count on "DC02" is 2, but because the bad password attempts were forwarded to the DC with the PDC Emulator role, this DC now reflects the total bad password attempts. "DC03"
has badPwdCount of 5 and badPasswordTime of 42:55. Since lockoutObservationWindow was not exceeded, the account is locked out.
The next two logon attempts after the account is locked do not update any of the attributes. The user gets the message that the account is locked, even when the correct password, "Pas$00", is used. The final logon attempt in the table succeeds because the
lockoutDuration has expired. At this point, badPwdCount resets to zero on all DC's, but badPasswordTime remains unchanged.
One conclusion is that lockoutObservationWindow is the maximum amount of time between bad password attempts that update badPasswordTime before badPwdCount will reset. If a bad password attempt is made on a DC, and the current time exceeds badPasswordTime
plus lockoutObservationWindow, then badPwdCount is reset to 1. Then badPasswordTime on the DC is updated to the current time.
Because the domain controller with the PDC Emulator role is so important, we consider what happens if this DC is not available. Several tests were run with the DC that has the PDC Emulator role offline. Typical results are in the table below.
The first bad password attempt above was handled by DC02, since the workstation was connected to that domain controller. The value of the LogonServer environment variable was "DC02". This DC should have forwarded the bad password request to the DC with the
PDC Emulator role, but this DC was not available. Apparently, the request instead got forwarded to DC01, after a slight timeout delay. DC01 also incremented the value of badPwdCount on that DC. For some reason the badPwdCount got incremented a second time
on DC02. No documentation could be found for this behavior.
The next bad password attempt looks as if it was handled by DC01, because only the Count and Time on that DC was updated. It is almost as if the LogonServer switched to DC01 during the first password attempt. The third bad password matches the most recent
password for this user in password history, so the logon attempt is rejected but nothing is updated on either DC.
The fourth bad password attempt, with elapsed time 2:37 since the previous badPasswordTime, causes the count on DC01 to increment by one, but the count on DC02 increments to 5. At this point the account is locked out. The DC with the PDC Emulator role is
then connected to the network to see if anything gets updated on this DC on the next bad password attempt. But the next bad password attempt results in no updates on any of the domain controllers, since the account is locked. The final password attempt, after
another hour has gone by, succeeds because the lockoutDuration has passed and the password is finally correct. The badPwdCount resets on all of the DC's, as expected.
Notice that DC03 never got updated in this case with any bad password information. Also, the user actually only got 3 tries with bad passwords, other than the one in recent password history, before getting locked out. Several similar tests were conducted
with the PDCe unavailable. In all cases, badPwdCount sometimes increased by more than one after a bad password attempt.
This feature helps reduce account lockouts and support calls to the help desk from regular users. However, it could reveal useful information to a potential attacker. A knowledgeable person doing a dictionary attack could monitor the value of badPwdCount
on the authenticating DC after each attempt. Such a person would be able to tell if an attempted password was among the two most recent in password history. This would not allow the attacker to compromise the account immediately. But it would provide useful
information. First, knowledge of past passwords can give hints about how the user constructs their passwords. Second, the attacker can assume the user will probably reuse an old password eventually.
Even assuming the information can be used by the attacker, the affect is that three passwords are being attacked rather than just one. The odds of identifying any of the three are only improved by a factor of 3 at most. As long as passwords are long and
complex, this is not a bad trade-off. Instead of an attack taking 3 years, it may take but one.
Also, this is only useful to someone with an existing account in the domain. If account lockout is configured the attacker needs to greatly reduce the number of attempts per minute, or risk lockouts.
The role of the PDC Emulator is the most critical for users. It is used for bad password attempts and password changes. The PDC Emulator in each domain serves as the primary time source for all computers in the domain, while the PDC Emulator in the forest
root domain is the primary time source for the forest. As such, the following is recommended.
There is always a tradeoff between security and convenience. If the network is very secure, but users are constantly making calls to the help desk to unlock their account, the balance may be wrong. Perhaps the best recommendations are those by Microsoft
in the blog post
Configuring Account Lockout. However, each organization should evaluate what is best for them, considering the sensitivity of the information in their environment, the risks they can tolerate, and their users.
Configuring password complexity greatly increases security. The universe of possible characters in any password becomes 94. This is much better than allowing a password among just the 26 lower case letters. The minimum password length is also critical for
increasing the number of possible passwords.
The maxPwdAge, lockoutThreshold, lockoutObservationWindow, and lockoutDuration attributes determine how many attempts an attacker can make in a period of time. If passwords never expire, or account lockout is not configured, the time becomes unlimited.
Enforcing password history prevents users from reusing passwords. However, to be affective, the minimum password age must be long enough to discourage users from changing their password multiple times to get back to one favorite.
Several blog posts recommend not configuring account lockout. Two are linked in the "Other Resources" section below. The argument is that there are many devices and applications today that authenticate automatically. If they have old passwords, many will
retry multiple times, causing lockouts. However, this argument is only valid if a protocol other than Kerberos or NTLM is used.