It’s common to want to retrieve password expiration dates for users by querying Active Directory directly. Conversely, you might want to obtain a list of all users whose passwords will expire soon. Of course, you cannot use Active Directory Users & Computers to view the password expiration value and tools like ADSI Edit can only display data that is in AD. Since the password expiration date for a user is calculated and not stored directly in AD, you have to take a different approach to make this work.
Active Directory calculates password expiration by reading the date when a user’s password was last changed (using the pwdLastSet attribute) and then reading the password policy (for the domain or AD container, depending on your AD functional level) for the account to determine the maximum password age. These two values are added to determine the password expiration value.
password change date + password policy maximum password age = password expiration date
Sounds easy enough, eh? The calculation is easy. What’s not easy is getting the values for the password change date (pwdLastSet) and the policy maximum password age (maxPwdAge). These values are stored internally in AD as LargeInteger, an 8-byte integer value. Your calculation needs to convert these internal data types for comparison to human-readable dates. Fortunately, there are easy conversion methods for converting these data types and the code samples at the end of this article show you these methods.
Web Active Directory provides PeopleMinder, a simple-to-deply solution to send notifications to users with expiring passwords, and this solution uses the password expiration calculation at its core to search for these users. You should check out PeopleMinder if you want a robust method to send out password expiration reminders on a daily basis.
Code Samples
Check out the code samples linked below for more information about calculating the AD password expiration date. You can then use these calculations to search for users whose passwords will expire soon. If you are a .NET developer, the Directory Programming .NET site at http://directoryprogramming.net/ is a fantastic resource for writing this type of password expiration date code. In fact, the site is a fantastic resource for all types of AD management code.
Scripts
- How to obtain password expiration date by using LDAP ADSI provider: http://support.microsoft.com/kb/323750
- How Long Until My Password Expires?: http://msdn.microsoft.com/en-us/library/ms974598.aspx
- List When a Password Expires: http://www.cruto.com/resources/vbscript/vbscript-examples/ad/users/pwds/List-When-a-Password-Expires.asp
PowerShell
- PowerShell Script – Active Directory Password Expiration Report: http://www.lucidsolutionsgroup.com/activedirectory/57-password-expiration-report.html
- Find out when your Password Expires: http://blogs.msdn.com/b/adpowershell/archive/2010/02/26/find-out-when-your-password-expires.aspx
.NET
- Chapter 10 of The .NET Developers Guide to Directory Services Programming (view pages 360-370): http://ptgmedia.pearsoncmg.com/images/0321350170/samplechapter/Kaplan_ch10.pdf
Hi,
Lots of good information in your posting, I would like to tweet your blog post so I can visit again in the near future.
Feel free and let us know if you need anything from us
Is there a way to command AD to expire the password now. (I don’t want to “require user to reset password on next login” ) I am actually trying to test a system where a password has expired. Is there a way to do this?
Active Directory doesn’t actually store the password expiration date for a user. Instead, it stores a timestamp when the password was last set in the pwdLastSet attribute (http://msdn.microsoft.com/en-us/library/windows/desktop/ms679430(v=vs.85).aspx). The password expiration is then calculated based on the password policy applied to the user’s container, whether it’s domain-level policy or fine-grained policy. Thus, you cannot directly set a password expiration for a user without changing the password policy applied to the user. Check out the article “How maximum password age is implemented” at http://support.microsoft.com/kb/236373 for more information on this.
You might try to set the pwdLastSet value for a test user to a time that is prior to the password policy’s maximum password age. However, I believe you can only set that value to 0 or -1 so you might not be able to set the time you want. Plus, the value is stored as a large 64-bit number that represents dates (in UTC) as the number of 100-nanosecond intervals since 12:00 AM January 1, 1601. This is not the easiest thing for humans to read and requires you to convert the value to a human-readable format. Try the thread at http://social.technet.microsoft.com/Forums/en-US/winserverDS/thread/de38f0b0-660c-47f9-9a50-cc1e35608a97/ for some directions you might head here.
Thanks Jason, those links are very helpful. It looks like forcing my user to have an expired password is going to be a non-trivial task.
Yes, our engineers can tell you from experience that it’s not trivial to test password expirations. We had to set up these tests when developing our PeopleMinder solution and it took a lot of manipulation of the password policy in our test domain.
You might substitute a “mock” concept for this dependency if you’re using a test framework. In a mock scenario you can create any value you need for your test and you might be able to inject a suitable password expiration value for your needs.
Good luck!
I actually just also found this:
http://technet.microsoft.com/en-us/library/cc781633(WS.10).aspx
I followed the steps and it seems I can set the “MaxPasswordAge” property – you can’t set this below 1 day, so my test will need to wait until tomorrow.