How Can I Determine When a User Last Changed His or Her Password?

Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I determine when a user last changed his or her password?

— MG

SpacerHey, Scripting Guy! AnswerScript Center

Hey, MG. A long time ago one of the Scripting Guys worked at a local university. In one of the departments there it was easy to determine when a user last changed his or her password: that’s because the administrative assistant kept a list of all the users in the department, all their passwords, and the dates and times when those passwords were changed. Best of all, she kept that list in a folder out on her desk; that way if anyone ever forgot their password they could just grab the folder and look up their password.

And, yes, anyone else’s password as well.

So that’s one way to determine the last time a user changed his or her password. But here’s another way:

Set objUser = GetObject(“LDAP://CN=myerken,OU=management,DC=Fabrikam,DC=com”)
Wscript.Echo “Password last changed: ” & objUser.PasswordLastChanged

Yes, that is the entire script; this isn’t one of those Web sites where we just show you the beginning of something and then make you pay to see the rest. (Although now that we think about it….) If we want to know the last time Ken Myer changed his password we just need to do two things:

Bind to Ken’s user account in Active Directory.

Echo the value of the PasswordLastChanged attribute.

That’s all you have to do. Really.

Of course, we’re assuming that you’re talking about an Active Directory user account; it’s quite possible that you’re talking about a Windows NT 4.0 user account, or even a local user account. If so, we appear to have a bit of a problem; after all, you need to use the WinNT provider to access NT 4.0 or local user accounts, and the WinNT provider does not support the PasswordLastChanged attribute.

So does that mean we’re out of luck when it comes to NT 4.0 or local user accounts? Ah, you guys should know us better than that:

strComputer = “atl-ws-01”

Set objUser = GetObject(“WinNT://” & strComputer & “/kenmyer”)

intPasswordAge = objUser.PasswordAge
intPasswordAge = intPasswordAge * -1
dtmChangeDate = DateAdd(“s”, intPasswordAge, Now)

WScript.Echo “Password last changed: ” & dtmChangeDate

As you can see, this script is a tiny bit longer, but still pretty simple. We begin by connecting to the Ken Myer account (username kenmyer) on the computer atl-ws-01. (What if you wanted to connect to an NT 4.0 domain instead? That’s fine; just replace the value atl-ws-01 with the name of that domain.) We then grab the value of the PasswordAge attribute and store it in a variable named intPasswordAge.

How come we don’t just echo the value of PasswordAge? Well, PasswordAge actually represents the number of seconds that have expired since the password last changed. Suppose you get back an answer like this:


Off the top of your head, can you subtract 50725249 seconds from the current date and time and calculate when the password was last changed?

Really? Wow; that’s impressive. We couldn’t do that ourselves, however, so we let the script do it for us. To begin with, we took the value of intPasswordAge and multiplied it by -1:

intPasswordAge = intPasswordAge * -1

Why? Well, in the very next line of code we’re going to use the DateAdd function to determine the date the password was last set. To do that, we need to pass DateAdd three parameters:

The time interval we’re dealing with. Because PasswordAge is stored in seconds we use “s” as our first parameter.

The number of seconds to add to the current date. This is why we multiplied intPasswordAge by -1. We don’t really want to add intPasswordAge to the current date; that would give us a time somewhere out in the future. Instead, we want to subtract intPasswordAge from the current date; after all, intPasswordAge is the number of seconds that have elapsed since the password was last changed. Because adding a negative number is the same thing as subtracting a positive number, we multiply intPasswordAge by -1.

The current date and time. For that we use the VBScript function Now.

That’s it; the result of our equation is stored in the variable dtmChangeDate, and in the last line of code we echo the value of that variable. At the time we created and tested this script it told us the password was last changed on 11/22/2003 at 12:02:10 PM. (It also told us that we don’t do a very good job of keeping our local user account passwords up to date.)

Comments (8)

  1. Anonymous says:

    Suppose there are 100 DCs in domain. If I changed password on DC1, then will ” PasswordLastChanged” attribute gets synced immediately on DC100 ? I mean, whether syncing issue affects value of PasswordLastChanged on different DCs ?

  2. Anonymous says:

    Is there a way to run this script for all users within an OU, instead of just one user account?

  3. M Nordby says:

    Do you know of a way to track when a password for a Link Server on SQL Server?

  4. kimberly says:

    and where would I type this script at ?

  5. Cash Money says:

    Create a .txt file with the script in it and when you save it rename it to .vbs.  You can either double click the vbs and  it will pop up your output or from a command line, you can run cscript followed by the name of the .vbs file.

  6. EJ Pennyman says:

    The powershell way to do this is get-aduser myerken -Properties PasswordLastSet.

  7. R Martinez says:

    How would this be done in c#

Skip to main content