I need to get a list of users from Active directory whose passwords are expiring soon (say in 5 days).
I need to do this by adding a filter to the DirectorySearcher as it will be fastest. I have added the samaccountname pattern to the filter but I can't figure out how to add pwdLastSet to it. Ideally the filter would reduce the user list to only those who fulfill the password expiration criteria.
using (DirectoryEntry searchRoot = GetXYZAccountOU())
{
DirectorySearcher ds = new DirectorySearcher(searchRoot);
ds.SearchScope = SearchScope.Subtree;
ds.Filter = "(&" +
"(samaccountname=XYZ*)"
+ ")";
SearchResultCollection result = ds.FindAll();
foreach (SearchResult searchResult in result)
{
var de = searchResult.GetDirectoryEntry();
//long pwdLastSetVal = (long)de.Properties["pwdLastSet"][0];
//Console.WriteLine(de.Properties["displayName"].Value + ": " + DateTime.FromFileTimeUtc(pwdLastSetVal));
Console.WriteLine(de.Properties["displayName"].Value);
}
Console.Read();
}
Here XYZ is the starting letters of my users' samaccountname.
If I run this code I can get the displayName and some other attributes but not the pwdLastSet or the computed attribute msDS-UserPasswordExpiryTimeComputed while I can see both of them in the Active directory browser.
You have to know in advance how long passwords are valid for, and query the
pwdLastSetattribute. But of course the date is stored in a weird format.Let's assume they're valid for 30 days. Then you can construct the query like this:
Accounts can be set to never expire passwords, so you have to account for that in your query. The
userAccountControlcondition does that.If you don't want to use a magic number in your code, you can look up how long passwords are valid for on the domain by looking at the
maxPwdAgeattribute at the root of the domain (which is stored in a different, weird format):