Finding users who have not changed their password recently

(Last updated on December 2, 2021)

One of the primary challenges with implementing a new password policy in Active Directory is ensuring users have changed their passwords to be compliant with that new policy. As we cannot view users’ current passwords in plain text to confirm they meet length and complexity requirements (and in the case of Specops Password Policy, do not contain disallowed dictionary words), the next best approach is verifying that all users have changed their password since the date your new password policy was implemented.

You can manually check the pwdLastSet attribute on each user account to see when their password was last changed. Use ADSIEdit or Active Directory Users and Computers (with advanced features enabled) to view the attribute directly:

When using PowerShell to pull the attribute, you’ll see that the attribute is actually saved in what is known as ‘filetime’ format.

Filetime is a timestamp stored as a count of the number of 100-nanosecond intervals that have elapsed since midnight on January 1, 1601 (UTC).

An interesting example is to look at a user for whom the pwdLastSet attribute is 0 (i.e. ‘never’) — as is the case when the user is set to require password change at next logon:

To convert the timestamp to a readable format, we must convert it using code such as this:

get-aduser user0000 -properties pwdlastset | select @{Name="PasswordLastSet";Expression={[datetime]::FromFileTimeUTC($_.pwdlastset)}}

Running this on the user required to change password at next logon shows this result (good to know if you are wondering why it looks like some of your users last changed their password when Shakespeare was still alive – just a quirk of how Active Directory implements a required password change):

Running the same command against a user with an actual password, we can now see the actual date and time the password was last changed:

Note: Active directory uses this filetime format for other time-based attributes — e.g. lastlogon, lastlogontimestamp, accountExpires, badpasswordtime. The same PowerShell code can be used to convert those attributes into readable datetime format.

Back to the task at hand: the following PowerShell script will find all enabled users in a particular OU/container who have not changed their password since a particular date, excluding users that are set to require a password change at next logon. Just modify the searchdate and searchbase variables as needed to run in your environment.

$verbosepreference = "continue"  
$searchdate = "2019-05-01" #yyyy-MM-dd format  
$searchbase = "OU=Users,OU=Specops,DC=specopsdemo1,DC=com"  
$passwordsNotChangedSince = $([datetime]::parseexact($searchdate,'yyyy-MM-dd',$null)).ToFileTime()  
write-verbose "Finding users whose passwords have not changed since $([datetime]::fromfiletimeUTC($passwordsNotChangedSince))"  
Get-ADUser -filter { Enabled -eq $True } `  
                    –Properties pwdLastSet `  
                    -searchbase $searchbase |   
    where { $_.pwdLastSet -lt $passwordsNotChangedSince -and `  
            $_.pwdLastSet -ne 0 } |   
    Select-Object name,sAmAccountName,  

Tags: , ,

Written by

Darren Siegel

Product Specialist, Specops Software

More Articles
Back to Blog