Native password policy for Microsoft Active Directory is only good enough to implement the most basic password policy.
Typically companies opt for an 8 character complex password, but what people don't realize is that with such a policy, the following are perfectly acceptable
Password1
Company1
Pass1word
...
What is disconcerting to me, is that without a third party password application (password filter) there is no way to prevent it.
This method outlines my process to nudge users in the right direction.
1) Create Password setting object with a shorter maximum age, I recommend less than 10 days.
2) Use DSInternals to do a password audit using common weak passwords and compromised accounts.
You can download it from https://www.dsinternals.com/en/downloads/ or install it with the following command
Install-Module DSInternals
DSInternals is a Powershell library created by Michael Grafnetter, an Identity & Security Premier Field Engineer (PFE) at Microsoft. It is an excellent library and should be part of your toolset if you have anything to do with security.
I have used it previously here:
Please note that if you install this via the Install-Module cmdlet, you will get a warning "Untrusted repository
You are installing the modules from an untrusted repository. If you trust this repository, change its
InstallationPolicy value by running the Set-PSRepository cmdlet. Are you sure you want to install the modules from
'PSGallery'?"
3) Clear the group that is assigned to Password Setting Object and add these violating accounts to it.
In this article I use DG-WeakPasswords
Import the DS Internals module
Import-Module DSInternals
Set the name of the group that was configured in the fine-grained password policy
$group = "DG-WeakPasswords"
Set the fully qualified domain name (FQDN)
$domainFQDN = "contoso.com"
Set the distinguished name (DN)
$domainDN = "dc=contoso,dc=com"
Build an NT hash dictionary file from the password.txt text file. The password.txt file contains a list of weak password that should not be allowed in the Active Directory. Don't have a password list? Get one here:
Get-Content $passwordFile | ConvertTo-SecureString -AsPlainText -Force | ConvertTo-NTHash | out-file $dictionaryFile
Get a collection object which contains all the accounts from Active Directory including their hashes
$accounts = Get-ADReplAccount -All -Server $domainFQDN
Optional: If you want to test your current password strength to get the crackable passwords, you can convert the object to a HashCatNT list with the command below and submit it on HashKiller.
$accounts | Format-Custom -View HashcatNT
For more information, see my How to extract hashes from IFM backup article https://www.experts-exchange.com/articles/29569/How-to-extract-hashes-from-IFM-backup.html
Test the quality of the passwords using the $dictionary object
$output = $accounts | Test-PasswordQuality -WeakPasswordHashes $dictionary -ShowPlainTextPasswords -IncludeDisabledAccounts
Clear the group. All user passwords need to be audited from scratch because some might have changed their passwords to a secure one
Get-ADGroupMember $group | ForEach-Object {Remove-ADGroupMember $group $_ -Confirm:$false}
Add all users that failed password audit to the group:
foreach($user in $output.WeakPassword) { Add-ADGroupMember -Identity $group -Members $user.Name}
Here's the complete script:
Import-Module DSInternals
$group = "WeakPasswords"
$domainFQDN = "contoso.com"
$domainDN = "DC=contoso,DC=com"
$dictionaryFile = ".\ntlmhashes.txt"
$passwordFile = ".\passwords.txt"
Get-Content $passwordFile | ConvertTo-SecureString -AsPlainText -Force | ConvertTo-NTHash | out-file $dictionaryFile
$accounts = Get-ADReplAccount -All -Server $domainFQDN
$output = $accounts | Test-PasswordQuality -WeakPasswordHashesfile $dictionaryFile -ShowPlainTextPasswords -IncludeDisabledAccounts
Get-ADGroupMember $group | ForEach-Object {Remove-ADGroupMember $group $_ -Confirm:$false}
foreach($user in $output.WeakPassword) { Add-ADGroupMember -Identity $group -Members $user.Name}
The result of this script is that the group will contain all the users that are using weak passwords. This forces a password policy - using fine-grained password policies - on them, that allows their passwords to be valid for fewer days than if they were to have specified a strong password
I hope you found this Powershell script useful, I guarantee that your password quality will drastically increase.
You are encouraged to ask questions, report any bugs or make any other comments about it below.
Note: If you need further "Support" about this topic, please consider using the Ask a Question feature of Experts Exchange. I monitor questions asked and would be pleased to provide any additional support required in questions asked in this manner, along with other EE experts...
Don't forget to press the "Thumbs Up" button if you think this article was helpful
It also provides me with positive feedback. Thank you!
Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.
Comments (3)
Commented:
Can the DSInternals module be installed in another computer without RSAT installed?
Because I wanted to run the scheduled task for this report to send out email alert, not from the Domain Controller.
Author
Commented:Just remember that you do not need DA. Configure an account with replicate directory access an use that in your scheduled task
Commented:
Open in new window
I have tested this code on the DC itself, that's why I use "localhost" as servername.