Auditing Active Directory Password Quality

August 7, 2016 | Michael Grafnetter


The latest version of the DSInternals PowerShell Module contains a new cmdlet called Test-PasswordQuality, which is a powerful yet easy to use tool for Active Directory password auditing. It can detect weak, duplicate, default, non-expiring or empty passwords and find accounts that are violating security best practices. All domain administrators can now audit Active Directory passwords on a regular basis, without any special knowledge.


The Test-PasswordQuality cmdlet accepts output of the Get-ADDBAccount and Get-ADReplAccount cmdlets, so both offline (ntds.dit) and online (DCSync) analysis can be done:

Although the cmdlet output is formatted in a human readable fashion, it is still an object, whose properties can be accessed separately (e.g. $result.WeakPassword) to produce a desired output.


I would like to thank Jakob Heidelberg for his idea to use the DSInternals module for password auditing. A big thank you also goes to Ondrej Sevecek for sharing his comprehensive auditing tool called SAPHA, from which I borrowed ideas for a few tests.

Tags: , ,

30 comments on “Auditing Active Directory Password Quality

  1. Denis says:

    Get-ADReplAccount : Cannot set percent because PercentComplete cannot be greater than 100.
    Parameter name: value
    Actual value was 101.
    At line:1 char:1
    + Get-ADReplAccount -All -Server dc-01 -NamingContext ” …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidArgument: (:) [Get-ADReplAccount], PSArgumentOutOfRangeException
    + FullyQualifiedErrorId : ArgumentOutOfRange,DSInternals.PowerShell.Commands.GetADReplAccountCommand

  2. Thomas says:

    Hello Michael

    thank you very much for sharing your great tools and informations! It’s really strange that Microsoft does not provide such tools by itself.

    I’ve testet our password quality and we have a problem: for some tests, it’s very hard to guess which concrete problem the test is addressing. For example: “These administrative accounts are allowed to be delegated to a service”. Until today, I thought every Account can be delegated to a service – which is probably wrong.

    It would be great if you could add some keywords or links to the different tests, so that we can study the background and plan the next steps.

    Thanks a lot in advance,
    kind regards,

    • Michael Grafnetter says:

      Hi Thomas, I admit that some some of those tests can only be understood by people with very deep AD knowledge. There is a good blog post about delegation written by a Microsoft employee. Also check out the Thycotic Weak Password Finder, which I have also programmed. It does the same tests as the Test-PasswordQuality cmdlet, is bundled with a nice list of common passwords and its reports contain simple explanations of the checks. Is there any other test you would like to know more about?

  3. Craig Atkins says:

    Hi Michael,

    How large can the password list be for this, and would we be able to calculate a password list once to NT Hashes and then save the hashes for quicker future audits on the same server?

    I’ve copied over the password list from your Weak Password Finder tool (which is very quick) and I’ve had the Test-PasswordQuality cmdlet running for around 20 mins without returning anything yet.



    • Michael Grafnetter says:

      I haven’t implemented a way of serializing the hash table, because the calculation is very quick. The Test-PasswordQuality cmdlet should not run that long, even on large ADs. I think that I have tested it on a 30M list without any problems.

      There might be a bug in the cmdlet. Do you have any updates on it?

  4. Fran├žois says:

    Hi. After this test, I have users in the sections “LM hashes of passwords of these accounts are present:”. How do I fix the problem?

  5. Matthew Dreher says:

    This utility is very helpful. I would also love to have a way of serializing the NT Hashes so that it can be imported and exported easily.

  6. joshua dorrs says:

    I’m seeing an odd behavior when running it in a script. Ultimately am running:

    $Results = Get-ADReplAccount -All -Server -NamingContext “DC=domain,dc=com” | Test-PasswordQuality -WeakPasswordHashes $dictionary -ShowPlainTextPasswords But I get weird issues/ errors:

    Test-PasswordQuality : Item has already been added. Key in dictionary: ‘AusersSamAccountName’ Key being added: ‘AusersSamAccountName’
    At line:1 char:191
    + … n,dc=com” | Test-PasswordQuality -WeakPasswordHashes $dictionary -Sho …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [Test-PasswordQuality], ArgumentException
    + FullyQualifiedErrorId : System.ArgumentException,DSInternals.PowerShell.Commands.TestPasswordQualityCommand

    This user is not a duplicate that I can find…

  7. Craig Atkins says:

    Hi Micheal,

    Sorry for the slow reply – I am running with a ~500MB password list and a 150 user AD, which is why it’s quite slow.

    It still works well though, thanks!

  8. Hugh Kelley says:

    Is there any way to use this excellent library with SHA-1 hashes, such as those available for download from

  9. Scot says:

    Hi Michael,

    Thanks for supplying this tool. I just downloaded from Github and installed. When I run the line $dictionary = Get-Content passwords. txt | ConvertTo-NTHashDictionary it seems to run for a while and then get the following error:

    ConvertTo-NTHashDictionary : Cannot validate argument on parameter ‘Input’. The argument is null or empty. Supply an argument that is not null or empty and then try the command again.
    At line:1 char:43 + $dictionary = Get-Content passwords.txt | ConvertTo-NTHashDictionary + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidData: (:PSObject) [ConvertTo-NTHashDictionary], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,DSInternals.PowerShell.Commands.ConvertToNTHashDictionaryCommand I am afraid I am far from a PowerShell expert. I created a smaller passwords.txt file and then I did not get the error. What kind of work-around can I do to use a large file? The one I originally used is about 175MB and comes from the KnowBe4 Weak Password Test passwords file. It contains about 11 million passwords. I am running your powershell module on a virtual windows 2012 server. Do you think I just need to up the available memory?

  10. Fady says:

    i tried the script and working amazing. but my issue with -showpassword is not working. what i have to do ?

  11. Priyanka says:

    Hi Michael, I am facing one of the weird issue with the testpassword quality when it is ran against the complete domain we are not getting the outputs for weak passwords in dicitionary at all and histroical section is missing altogether in the report. DO you think there might be something missing in the way I am running it .

    It is the same command which I am using to run it as above post.

  12. Greg says:

    Hi Michael, The v.3.4 release of dsinternals is amazing, especially the search improvements. My ‘regular’ search time went from 7h:30m to 27m (opening the HIBP NTLM file across a UNC share). It’s even faster with the ‘sortedfile’ switch: 52 seconds with the HIBP NTLM file local; only 1m20s across a UNC share. Wow!

  13. ravi kumar says:

    i am new to this tool. can you please let me know if i can run this tool in a production environment without getting user accounts lockouts?

    Get-ADReplAccount -All -Server $dc -NamingContext $domain | Test-PasswordQuality -WeakPasswordHashes $dict -ShowPlainTextPasswords -IncludeDisabledAccounts

  14. kumar says:

    HI Michael,

    My management is requesting to identify user using a particular password for example “test@123”.how can I implement this using Get-ADReplAccount? I tried to use older version it is not working .any suggestions?

  15. Akila says:

    This is a awesome tool. But when i used the Test-PasswordQuality cmdlet i received the following error could you please help here.

    Test-PasswordQuality : A parameter cannot be found that matches parameter name ‘WeakPasswordHashesSortedFile’.

  16. hey, first of all, love the module, a really powerful tool. I am having a slight issue with formating however, the output of Test-Password shows

    These groups of accounts have the same passwords:
    Group 1:
    Group 2:

    however the if I take $result.DuplicatePasswordGroups I get

    DOMAIN\USER4 is it possible to get the users and group data without displaying the entire output as there are things we don’t need such as non-expiring passwords

Leave a Reply

Your email address will not be published.