This gets me data that I have been manually massaging into Excel, which is a pain - I want to run the report once a month, and perhaps ad hoc on occasion.
Get-ADReplAccount -All -Server dc1 -NamingContext "dc=example,dc=org" | Test-PasswordQuality -WeakPasswordHashesFile c:\temp\pwned-passwords-ntlm-ordered-by-hash-v6.txt
What I want is one samAccountName per line, with the results columns ticked for each attribute that affects that account (except the group number of the shared passwords)
So, one entry might look like this:
ID PWDLastSet LM Hash Present Found in Dictionary Same Password KerbMissingAESKey DelegationToServiceAllowed PWDNeverExpires PWDNotRequired
User1 2018-09-06 09:22 Group06 x x
If you follow that out, you'll see that User1 had the password changed a long time ago, that its password is shared in group 6, that the account is allowed to be delegated to a service and that the password is set to never expire.
The password last set date comes from a separate query, so it's not hugely important to have that field immediately available.
So, I broke it out a little bit, into this:
$Repl = Get-ADReplAccount -All -Server gfcdc0 -NamingContext "dc=csww,dc=lan"
$pwdResults = $Repl | Test-PasswordQuality -WeakPasswordHashesFile c:\temp\pwned-passwords-ntlm-ordered-by-hash-v6.txt
I piped the output of $pwdResults to gm, and that looks straightforward, but each of the properties seems to consist of a header line and then the set of samAccountNames within that that attribute, and I can't figure out how to parse it out.
$pwdResults | gm
TypeName: DSInternals.PowerShell.PasswordQualityTestResult
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
AESKeysMissing Property System.Collections.Generic.ISet[string] AESKeysMissing {get;set;}
ClearTextPassword Property System.Collections.Generic.ISet[string] ClearTextPassword {get;set;}
DefaultComputerPassword Property System.Collections.Generic.ISet[string] DefaultComputerPassword {get;set;}
DelegatableAdmins Property System.Collections.Generic.ISet[string] DelegatableAdmins {get;set;}
DESEncryptionOnly Property System.Collections.Generic.ISet[string] DESEncryptionOnly {get;set;}
DuplicatePasswordGroups Property System.Collections.Generic.IEnumerable[System.Collections.Generic.ISet[string]] DuplicatePasswordGroups {get;set;}
EmptyPassword Property System.Collections.Generic.ISet[string] EmptyPassword {get;set;}
LMHash Property System.Collections.Generic.ISet[string] LMHash {get;set;}
PasswordNeverExpires Property System.Collections.Generic.ISet[string] PasswordNeverExpires {get;set;}
PasswordNotRequired Property System.Collections.Generic.ISet[string] PasswordNotRequired {get;set;}
PreAuthNotRequired Property System.Collections.Generic.ISet[string] PreAuthNotRequired {get;set;}
SmartCardUsersWithPassword Property System.Collections.Generic.ISet[string] SmartCardUsersWithPassword {get;set;}
WeakPassword Property System.Collections.Generic.ISet[string] WeakPassword {get;set;}
Any pointers on this would be appreciated.
Kurt