Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124

Managing password policies and tracking password changes is a critical aspect of enterprise security. As system administrators, we often need to verify when users last changed their passwords to ensure compliance with organizational security policies or troubleshoot authentication issues. This comprehensive guide explores multiple methods to retrieve last password change information for domain users in Active Directory.
Before diving into the methods, it’s essential to understand the key Active Directory attributes related to password changes:
PowerShell provides the most flexible and scriptable approach for retrieving password information. The Active Directory module offers cmdlets specifically designed for this purpose.
# Import the Active Directory module
Import-Module ActiveDirectory
# Get password information for a specific user
$user = Get-ADUser -Identity "john.doe" -Properties PasswordLastSet, PasswordExpired, PasswordNeverExpires
Write-Host "User: $($user.Name)"
Write-Host "Last Password Change: $($user.PasswordLastSet)"
Write-Host "Password Expired: $($user.PasswordExpired)"
Write-Host "Password Never Expires: $($user.PasswordNeverExpires)"
# Get password information for all users in a specific OU
$users = Get-ADUser -SearchBase "OU=Users,DC=company,DC=com" -Filter * -Properties PasswordLastSet, PasswordExpired, PasswordNeverExpires
# Display results in a formatted table
$users | Select-Object Name, SamAccountName, PasswordLastSet, PasswordExpired, PasswordNeverExpires | Format-Table -AutoSize
# Find users who haven't changed passwords in the last 90 days
$cutoffDate = (Get-Date).AddDays(-90)
$stalePasswords = Get-ADUser -Filter * -Properties PasswordLastSet |
Where-Object { $_.PasswordLastSet -lt $cutoffDate -and $_.PasswordLastSet -ne $null } |
Select-Object Name, SamAccountName, PasswordLastSet
# Export to CSV for reporting
$stalePasswords | Export-Csv -Path "C:\Reports\StalePasswords.csv" -NoTypeInformation
For environments where PowerShell might not be available, traditional command-line tools can be used:
# Query user and get password last set information
dsquery user -name "John Doe" | dsget user -pwdlastset -display
# Basic user information including password details
net user john.doe /domain
For more advanced scenarios or integration with custom applications, direct LDAP queries can be performed:
# Direct LDAP query for password information
$searcher = New-Object System.DirectoryServices.DirectorySearcher
$searcher.Filter = "(&(objectClass=user)(sAMAccountName=john.doe))"
$searcher.PropertiesToLoad.Add("pwdLastSet") | Out-Null
$searcher.PropertiesToLoad.Add("name") | Out-Null
$result = $searcher.FindOne()
if ($result) {
$pwdLastSet = $result.Properties["pwdlastset"][0]
$passwordDate = [DateTime]::FromFileTime($pwdLastSet)
Write-Host "Password Last Set: $passwordDate"
}
For administrators who prefer graphical interfaces:
Active Directory stores timestamps as FILETIME values (64-bit integers representing 100-nanosecond intervals since January 1, 1601). PowerShell automatically converts these to readable DateTime objects.
Implement automated scripts to regularly check password ages across your organization:
# Scheduled task script for password monitoring
$warningDays = 30
$criticalDays = 90
$warningDate = (Get-Date).AddDays(-$warningDays)
$criticalDate = (Get-Date).AddDays(-$criticalDays)
$users = Get-ADUser -Filter * -Properties PasswordLastSet | Where-Object { $_.Enabled -eq $true }
foreach ($user in $users) {
if ($user.PasswordLastSet -lt $criticalDate) {
Write-Warning "CRITICAL: $($user.Name) - Password age exceeds $criticalDays days"
} elseif ($user.PasswordLastSet -lt $warningDate) {
Write-Warning "WARNING: $($user.Name) - Password age exceeds $warningDays days"
}
}
Create comprehensive reports for security audits and compliance requirements:
# Generate compliance report
$report = Get-ADUser -Filter * -Properties PasswordLastSet, PasswordExpired, PasswordNeverExpires, LastLogonDate |
Select-Object @{
Name = "Username"
Expression = { $_.SamAccountName }
}, @{
Name = "Display Name"
Expression = { $_.Name }
}, @{
Name = "Password Last Set"
Expression = { $_.PasswordLastSet }
}, @{
Name = "Days Since Password Change"
Expression = {
if ($_.PasswordLastSet) {
(New-TimeSpan -Start $_.PasswordLastSet -End (Get-Date)).Days
} else {
"Never Set"
}
}
}, @{
Name = "Password Expired"
Expression = { $_.PasswordExpired }
}, @{
Name = "Last Logon"
Expression = { $_.LastLogonDate }
}
$report | Export-Csv -Path "C:\Reports\PasswordCompliance.csv" -NoTypeInformation
Create reusable functions for password checking:
function Get-PasswordAge {
param(
[Parameter(Mandatory=$true)]
[string]$Username
)
try {
$user = Get-ADUser -Identity $Username -Properties PasswordLastSet
if ($user.PasswordLastSet) {
$age = (New-TimeSpan -Start $user.PasswordLastSet -End (Get-Date)).Days
return [PSCustomObject]@{
Username = $Username
PasswordLastSet = $user.PasswordLastSet
PasswordAge = $age
}
} else {
return [PSCustomObject]@{
Username = $Username
PasswordLastSet = "Never Set"
PasswordAge = "N/A"
}
}
} catch {
Write-Error "Error retrieving password information for $Username: $($_.Exception.Message)"
}
}
Monitoring password change dates and times is crucial for maintaining security hygiene in Active Directory environments. Whether you prefer PowerShell automation, command-line tools, or graphical interfaces, Active Directory provides multiple methods to track this vital security information.
Regular monitoring, automated reporting, and proactive password policy enforcement help ensure your organization maintains strong security posture while meeting compliance requirements. By implementing the methods and best practices outlined in this guide, administrators can effectively manage and monitor password lifecycles across their domain infrastructure.
Remember to always test scripts in a non-production environment first and ensure you have appropriate permissions and backups before making any changes to Active Directory objects.