Only the most basic password length, frequency, and complexity requirements can be enabled for domain users in the default Active Directory password policy. Enabling the mandatory password complexity option, which requires passwords to contain a mix of uppercase, lowercase letters, numbers, and special characters, doesn’t prevent users from using easily guessable passwords like Qwerty123456
, P@ssw0rd
, March2025
, etc. These passwords meet the complexity criteria but remain vulnerable to attack due to their predictability.
This guide explains how to create and enforce banned password lists in an on-premises Active Directory domain, preventing users from setting weak or compromised passwords and protecting accounts from dictionary and brute-force attacks.
Banned Password List with AD Password Filter (PassFiltEx)
First, let’s take a look at PassFiltEx, a lightweight open-source library that provides a simple solution for blocking common weak passwords in Active Directory
When an AD user changes a password, the LSA process on the domain controller checks whether the password matches the registered password filters. The PassFiltEx library can be used transparently as an additional filter when checking a new password.
To implement PassFiltEx, download two files from the project’s GitHub page (https://github.com/ryanries/PassFiltEx) and copy them to the %SystemRoot%\System32
directory on a domain controller.
- PassFiltEx.dll – PassFiltEx library file
- PassFiltExBlacklist.txt – a plain text file containing the passwords you want to deny in AD
- PassFiltEx reloads the blocklist file every 60 seconds
- The denied password patterns in the PassFiltExBlacklist.txt file are not case-sensitive. (
MyPasswordD
andmypassword
values will be defined as equal) - Unicode characters are not currently supported
Then, open the Registry Editor, go to the HKLM\SYSTEM\CurrentControlSet\Control\Lsa
key, and add the PassFiltEx value to the end of the Notification Packages multi-string parameter.
Restart the domain controller to apply the new password filter. Verify that the lsass process loads the PassFiltEx library.
tasklist /m PassFiltEx.dll
Now, if the user tries to change the password to any one that matches one of the patterns in the password blacklist, an error will appear stating that the password doesn’t meet the password policy requirements.
If you have multiple domain controllers deployed, configure the same password filter on each of them.
Using registry options in the HKLM\SOFTWARE\PassFiltEx
reg key (created automatically), you can configure additional PassFiltEx password filter settings:
- BlacklistFileName (REG_SZ) – path to the file containing the banned passwords. (default is
%SystemRoot%\System32\PassFiltExBlacklist.txt
). A UNC path can be used here, which allows the file to be stored in the SYSVOL (to use a single password blacklist file that is automatically replicated between DCs) - TokenPercentageOfPassword (REG_DWORD) – is the minimum percentage of a new password matching a blacklisted template that will cause the password to be rejected (by default is 60%). For example, if you add a line with the pattern MyPasswd to the blacklist, users will not be able to use the password MyPasswd2025.
- Debug – If set to 1, it enables debug mode (all actions are logged to a text file).
- BlockSequentialChars – block the use of character sequences in the password, such as abcd or 1234.
- BlockRepeatingChars — block sequences of identical characters like AAAA, 2222.
Information about other registry options can be found on the project’s GitHub page.
Block Weak and Compromised Passwords with Lithnet Password Protection
Lithnet Password Protection for Active Directory (LPP) is an enterprise solution for blocking weak and compromised passwords in Active Directory. Its basic functionality allows to extend AD password policy requirements, block passwords using templates or password hashes (allows to import a database of compromised passwords from external dictionaries). Lithnet Password Protection supports management via Group Policy and PowerShell.
The Lithnet Password Protection for Active Directory agent should be installed on each domain controller (https://github.com/lithnet/ad-password-protection).
Then, use PowerShell to add prohibited passwords and keywords to the Lithnet password vault. Import the module into your PowerShell session:
Import-Module LithnetPasswordProtection
Add a word you want to block from being used in AD user passwords.
Add-BannedWord -Value "admin"
You can import the list of banned keywords from a text file:
Import-BannedWords -Filename "c:\temp\blacklistpwd.txt"
Check LPP database for banned word:
Test-IsBannedWord -value admin
Use the Get-PasswordFilterResult cmdlet to test whether the password that you typed complies with the password policy:
Get-PasswordFilterResult -Password "Admin321" -Username jsmith -Fullname "John Smith"
Compromised
Get-PasswordFilterResult -Password "Adm123n!" -Username jsmith -Fullname "John Smith"
Approved
In the first case, the password contains the exact match of the keyword Admin, and the password policy prohibits its use.
LPP’s password vault is a file-based password hash database (because of the binary format, searching such a database is fast). By default, DB files are stored in the C:\Program Files\Lithnet\Active Directory Password Protection\Store\v3\p
directory. DFS-R is used to replicate the Lithnet Password Protection database of banned passwords between domain controllers.
Lithnet Password Protection (LPP) allows administrators to import compromised passwords from the “Have I Been Pwned” (HIBP pwnded) service into a local database, increasing security by preventing users from selecting passwords exposed in data breaches. This will require about 8 GB of disk space on the DC to store the hash dictionary.
Sync-HashesFromHibp
Or import hashes from a text file:
Import-CompromisedPasswordHashes -Filename "c:\ps\pwned-ntlm-hashs.txt"
Check if the specific password or user’s UPN is in the database of compromised passwords.
Test-IsCompromisedPassword -value MyAdminl0veSme
Test-IsADUserPasswordCompromised -upn [email protected]
Administrative template files (ADMX) are available to manage LPP settings via GPO. By default, the ADMX templates can be found in the %WINDIR%\PolicyDefinitions\
directory on a DC with an LPP agent (you can copy them to the central GPO store):
- lithnet.activedirectory.passwordfilter.admx
- lithnet.admx
- \en-us\lithnet.activedirectory.passwordfilter.adml
- \en-us\lithnet.adml
To have the LPP agent check a user’s password against the blacklist password dictionary when the user changes the password, create a GPO for domain controllers with the following minimum settings under Computer Configuration -> Administrative Templates -> Lithnet ->Password Protection for Active Directory -> Default Policy section.
- Reject passwords found in the compromised password store –
Enable
, uncheck the options Enable for password set and Enable for password change operations. - Reject normalized password found in the compromised password store (deny normalized passwords, for example, WOSHub and woshub)
Other GPO options can be enabled/disabled depending on your security needs.
Restart the domain controller to update the GPO settings. This will also add the lithnetpwdf password filter to the registry key specified above.
Now, when trying to change (reset) an AD user’s password, an additional check is performed to see if the password is in the dictionary of forbidden passwords. For example, Windows 11 displays the following error:
The password on this account cannot be changed at this time
Obviously, this is inconvenient because it is not clear to the user that their password has failed to pass the password policy check.
We’ve explored how to improve Active Directory security by implementing open-source solutions that prevent the use of weak, leaked, or common passwords that are not typically blocked by default AD password policy.