Do you want to know whether your Active Directory (AD) users are using weak AD passwords? And what is a weak AD password anyway? The term can be confusing and can mean something else entirely, depending on the context.
One thing is sure—auditing your environment for weak AD passwords is crucial to securing your organization. And if you don’t know how to begin, keep reading because this tutorial will teach you how to use PowerShell to find weak passwords of your AD users.
This post is kindly sponsored by Specops Software. Be sure to check out their handy password auditor tool for a lot more features than you can build in a custom PowerShell script!
Prerequisites
This tutorial will be hands-on and if you plan to follow along, make sure to have the following requirements.
- You’ll need a domain-joined computer running any modern version of Windows. This tutorial will use a Windows Server 2019 Active Directory domain controller (DC).
- Windows PowerShell 5.1 or later.
- You must install the DSInternals PowerShell module on the computer. At the time of this writing, the latest version is 4.4.1, which this tutorial will use.
- You’ll also need a code editor where you’ll write the PowerShell script. This tutorial will use Windows PowerShell ISE.
- Your user account must be a member of the Domain Admins group in Active Directory.
- You also need to know the DC’s hostname and the domain partition naming context (NC). In this tutorial, the DC’s hostname is “poshlabdev01.posh.lab” and the NC is “dc=posh,dc=lab.”
You can find the DC’s hostname and the NC by running the
Get-ADDomainController
cmdlet and getting theHostName
andDefaultPartition
property values, respectively.
- A copy of the Top 100K PwnedPasswords List text file from the National Cyber Security Centre (NCSC). This file contains the list of top 100,000 breached or commonly reoccurring passwords. In this tutorial, the file will be in C:\ATA\PwnedPasswordsTop100k.txt.
NCSC is a London-based organization that specializes in cyber-security. And together with the Have I Been Pwned website, NCSC released the top 100,000 breached passwords set.
Finding Users with Weak AD Passwords using PowerShell
Even a seemingly strong password can also be a weak password. For example, GvqZvxUb76
appears to have password complexity characteristics. The password has uppercase and lowercase letters, digits, looks like randomly-generated and has no discernable pattern.
But this password is weak because it was part of leaked password lists resulting from previous data breach incidents. Consequently, this password may be subject to brute force or password spraying attacks.
So how do you find weak passwords in Active Directory? Use a breached password list such as the PwnedPasswordsTop100k.txt file from NCSC to compare your users’ passwords. And the how is where PowerShell and the DSInternals module come into play.
IMPORTANT: There is no clear information on the NCSC website or elsewhere if the PwnedPasswordsTop100k.txt file receives regular updates. According to this NCSC article entitled “Passwords, passwords everywhere,” the publish date was April 21, 2019.
The author has reached out to NSCS for confirmation and Troy Hunt and is awaiting a response.
UPDATE (September 27, 2021): According to the email reply from Troy Hunt, the 100k plain text passwords was a one-off provision to the NCSC.
Retrieving All AD User Accounts
Before you can test the password quality of an AD user account, you’ll need to retrieve the user account details first, including its password hash. And to do so, the Get-ADReplAccount
cmdlet is the tool to use. This cmdlet is part of the DSInternals PowerShell module.
In a nutshell, the password hash is the encrypted value of the user’s password in Active Directory.
To retrieve the user accounts, follow these steps.
1. Open PowerShell as administrator.
2. Next, run the command below to declare the variables for the DC’s hostname, NC, and the weak passwords list file location.
# Domain Controller hostname
$DC = 'poshlabdev01.posh.lab'
# Naming Context
$NC = 'DC=posh,DC=lab'
# Weak passwords file
$WeakPasswordsFile = 'C:\ATA\PwnedPasswordsTop100k.txt'
3. Now, get all user accounts and store the result to the $accounts
variable by running the Get-ADReplAccount
command below in PowerShell.
# The -All switch tells the cmdlet to get ALL accounts.
# The -Server parameter accepts the name of the target domain controller.
# The -NamingContext parameter accepts the naming context of the domain.
# The "Where-Object {$_.SamAccountType -eq 'User'}" filters the result to return only the 'User" account type.
$accounts = Get-ADReplAccount -All -Server $DC -NamingContext $NC |
Where-Object {$_.SamAccountType -eq 'User'}
# (OPTIONAL) Display the number of retrieved user accounts to confirm
$accounts.Count
The screenshot below shows that the command has returned 22 user accounts.
Testing the Password Quality
Now that you’ve retrieved all the AD user accounts, the next step is to test each user’s password quality using the Test-PasswordQuality
cmdlet. This cmdlet is also part of the DSInternals module.
To test the password quality of the users, proceed as follows.
1. Copy the command below and run it in PowerShell. This command will test each user account’s password, including the disabled user accounts, against the NCSC weak passwords list file. In the end, the $result
variable will contain the password quality test results.
# The -IncludeDisabledAccounts switch will include disabled user accounts in the testing.
# The -WeakPasswordsFile parameter accepts the location of the weak passwords list file.
$result = $accounts | Test-PasswordQuality -IncludeDisabledAccounts -WeakPasswordsFile $WeakPasswordsFile
2. After the test has finished, the $result
variable will contain many different results that you can view. Specifically, run the command below to view the accounts with passwords that matched the weak passwords list. $result.WeakPassword
$result.WeakPassword
In this example, there was one user account whose password appears in the NCSC’s top 100,000 breached passwords list.
3. At this point, if needed, export the result to a file for reporting purposes. To do so, pipe the result to the Out-File
cmdlet by running the command below. Make sure to change the destination filename in the -FilePath
parameter as needed.
$result.WeakPassword | Out-File -FilePath C:\ATA\result.txt
Creating the Weak AD Password Audit Tool
You now have a working logic framework on how to find weak AD passwords using PowerShell. If you plan to share your script so that others may run it themselves, you better turn your script into a tool to make it reusable.
In its current form, your script requires editing the code to change the variable values manually depending on the target environment. To avoid possibly tampering with the code, convert your script into a tool that accepts parameters instead.
Writing the Script
Follow the below steps to create the weak AD password reporting tool.
1. Open the code editor of your choice. This example uses Windows PowerShell ISE.
2. Create a new file and save it as Expose-WeakADPassword.ps1 to any folder you prefer. This example saves the file to the C:\ATA folder.
3. After you’ve created the script file Expose-WeakADPassword.ps1, copy the code below and paste it into your code editor, and save the script.
Refer to the inline comments for the descriptions of what the script does.
# Declare DSInternals as the required module.
# https://github.com/MichaelGrafnetter/DSInternals
#requires -Modules DSInternals
# Add a the required parameters
## [parameter(Mandatory)] - makes the parameter required
## [ValidateNotNullOrEmpty()] - validates that the parameter value is neither $null nor empty.
param (
# Accepts the domain controller's hostname (e.g., dc1.contoso.com)
[parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
$DomainController,
# Accepts the domain partition naming context (e.g., dc=contoso,dc=com)
[parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
$NamingContext,
# Accepts the location or path of the weak password list File (i.e., the NSCS Top 100,000 Breached (Pwned) Passwords)
[parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
$WeakPasswordsFile
)
# BEGIN WEAK AD PASSWORD TEST
(
<# GET ALL AD USER ACCOUNTS
1. Get all user accounts using the Get-ADReplAccount cmdlet.
* The -All switch tells the cmdlet to get ALL accounts.
* The -Server parameter accepts the name of the target domain controller.
* The -NamingContext parameter accepts the naming context of the domain.
2. The "Where-Object {$_.SamAccountType -eq 'User'}" filters the result to return only the 'User" account type.
3. Send the accounts through the pipeline "|"
#>
Get-ADReplAccount -All -Server $DomainController -NamingContext $NamingContext | Where-Object { $_.SamAccountType -eq 'User' } |
<# TEST ALL USERS' PASSWORD QUALITY
4. Test each accounts' password quality using the Test-PasswordQuality cmdlet.
* The -IncludeDisabledAccounts switch will include disabled user accounts in the testing.
* The -WeakPasswordsFile parameter accepts the location of the weak passwords list file.
#>
Test-PasswordQuality -IncludeDisabledAccounts -WeakPasswordsFile $WeakPasswordsFile
<# RETURN / DISPLAY THE RESULT
5. Return the ".WeakPasswords" property values containing the list of weak passwords users.
#>
).WeakPassword
# END WEAK AD PASSWORD TEST
Running the Script
Now that you have the tool to expose weak AD passwords follow the steps below to run the tool.
1. Open a PowerShell window as admin. But if you’re already using Windows PowerShell ISE, there’s already a PowerShell console available in the ISE window (see image below), and you can skip this step.
2. Next, change the working directory to where you saved the script by running the command below. In this example, the script is in C:\ATA.
Set-Location C:\ATA
3. Now, invoke the Expose-WeakADPassword.ps1
script. Remember that the script requires three parameter values—DomainController
, NamingContext
, and WeakPasswordsFile
. Run the script as shown below.
.\Expose-WeakADPassword.ps1 -DomainController 'poshlabdev01.posh.lab' -NamingContext 'DC=posh,DC=lab' -WeakPasswordsFile 'C:\ATA\PwnedPasswordsTop100k.txt'
After running the script, the output shows the user accounts with weak passwords or whose passwords matched the entries on the breached passwords list.
Another way to run the script for better readability is to use splatting, as shown in the code below.
$params = @{
DomainController = 'poshlabdev01.posh.lab'
NamingContext = 'DC=posh,DC=lab'
WeakPasswordsFile = 'C:\ATA\PwnedPasswordsTop100k.txt'
}
.\Expose-WeakADPassword.ps1 @params
And you can expect that the result should be the same.
You now have a working script to find weak AD passwords. You can further improve your script by adding more functionalities that you see fit. Like adding the users’ or manager’s email address in the output, perhaps?
Exploring the Specops Password Auditor
Most system admins, especially those who manage the AD, would be happy to create tools to solve challenges. Why? Creating and sharing tools gives them bragging rights, would look great in their credentials, and they’d have complete control over how the tool works and its customization.
But what if a free tool already exists that can produce the same results you need—and more? Which can mean that administrators can dedicate their time doing other essential tasks instead of creating and maintaining custom scripts.
And yes, such a free tool exists, and it is called Specops Password Auditor.
Scanning for Multiple Password-Related Weaknesses
Specops Password Auditor only scans the Active Directory and does not make any changes. This tool does not store, collect, or send any data anywhere.
The PowerShell script you created previously only compares passwords with the 100k breached password list from NCSC. In contrast, Specops Password Auditor uses an actively maintained database already containing over 750 million breached and weak passwords from multiple sources.
During its first run, Specops Password Auditor will ask to download the breached password database. The breached password database size is approximately 5GB containing entries from multiple breached password list sources.
Apart from scanning for weak AD passwords against a huge breached password database, Specops Password Auditor also scans for other password-related vulnerabilities such as:
- Blank Passwords – lists user accounts that have blank passwords.
- Identical Passwords – lists user accounts with identical passwords.
- Admin Accounts – lists user accounts having administrator privileges.
- Stale Admin Accounts – lists all administrator accounts whose last login time is older than a specified period (90 days default). The threshold range is from 30 days to 360 days.
- Password Not Required – lists user accounts whose accounts that do not require passwords.
- Password Never Expires – lists user accounts whose passwords do not expire.
- Expiring Passwords – lists user accounts whose passwords expire in a specific period (10 days default). This threshold ranges from 1 to 365 days.
- Expired Passwords – lists user accounts whose passwords have already expired.
- Password Policies – lists all the password policies that exist in your domain.
- Password Policy Usage – shows the distribution of users per password policy.
- Password Policy Compliance – compares your password policies with several industry standards and shows whether the policies are fully compliant, partially compliant, and non-compliant.
Viewing and Exporting Reports
After running a scan, Specops Password Auditor presents the scan results as individual cards. These cards represent the results of different scan types, as you can see below.
Gold cards are available to domain administrators only. Running the scan using a non-domain administrator account will only produce the blue cards.
To drill down a specific report, click on the card, and it will bring up the details for that report. For example, click on the Breached Passwords card to reveal the list of users with weak AD passwords, as shown below.
This report page also allows you to export the result to a CSV file. To do so, click the Export button, choose the location, and specify the filename. Finally, click Save to save the CSV file.
A CSV file export is excellent—but it is raw. Admins can use them for analysis, auditing, or as input for automation workflows. Similar to a report you get with a custom PowerShell script.
Another feature that sets Specops Password Auditor apart is its ability to export beautiful, professional-looking PDF reports. This type of report is what you’d want to present to your boss or the management.
To generate a PDF report, click the Get PDF Report button on the main reports page. Next, specify the PDF report options such as the file File path, Paper size, and Report type. Lastly, click Generate.
The Summary report includes only the summary of each finding. On the other hand, the Full report consists of the summary and the details (list of users, policies, list of stale admin accounts, etc.)
The screenshot below is an example of a summary report. As you can see, the report summarizes each finding, explains the risk, and gives recommendations on how to fix the issue when applicable.
Conclusion
WIth PowerShell, you can create a tool that finds weak AD passwords. And with (lots of) time and effort, you can customize your tool based on your requirements and even make use of other third-party breached passwords databases beyond the NCSC list.
Specops Password Auditor, on the other hand, can run a comprehensive list of password vulnerability scans. This tool also has access to an extensive database of breached passwords from multiple sources. Best of all, it is free and does not require you to code.
In the battle of customizability vs. convenience, is there a clear winner? Which tool do you prefer to expose weak AD passwords?