Finding users who have not changed their password recently

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,  
                  @{Name="PasswordLastSet";Expression={  
                      [datetime]::FromFileTimeUTC($_.pwdLastSet)  
                      }  
                  }  

Alternatively, system administrators can download Specops Password Auditor. The results provided will include when passwords were last changed along with other information about vulnerabilities found, including expired or compromised passwords (including whether any user’s password was found on a list of breached passwords).

(Last updated on June 24, 2022)

Tags: , ,

darren siegel

Written by

Darren Siegel

Darren Siegel is a cyber security expert at Specops Software. He works as a lead IT engineer, helping organizations solve complex challenges within IT security. Darren has more than 15 years’ experience within Active Directory, IT security, servers, storage, virtualization, cloud, and identity and access management.

Back to Blog

Related Articles

  • How to enforce password history in Active Directory

    The “Enforce password history” setting in Active Directory is used to determine the number of unique passwords a user must use before they can use an old password again. This is an important setting because password reuse is a common issue – the more often the same (or similar) password is used, the greater chance…

    Read More
  • Password expiration policy best practice

    Instead of arbitrarily expiring passwords every 90 or so days, why not configure the maximum password age based on the complexity level of a password?

    Read More
  • Helpdesk password reset best practices

    If your organization is currently using a self-service password reset solution, it is critical that the helpdesk staff who manage the system, and assist users, consistently follow best practices. This post will provide tips for reducing password-related calls to the helpdesk, and outline some security measures for safeguarding user accounts. Educate and direct to self-service…

    Read More