function Get-PasswordLastSet {
<#
.SYNOPSIS
Retrieves the date and time a user's password was last set.
.DESCRIPTION
This function queries Active Directory (if available) or the local Security Account Manager (SAM)
to determine the last time a specified user's password was changed.
.PARAMETER UserName
The username of the account to query.
.EXAMPLE
Get-PasswordLastSet -UserName "john.doe"
Displays the last password set date and time for the user "john.doe".
.EXAMPLE
Get-PasswordLastSet -UserName "administrator"
Displays the last password set date and time for the local Administrator account.
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
[Alias("SamAccountName")]
[string]$UserName
)
process {
try {
# Attempt to query Active Directory
$user = Get-ADUser -Identity $UserName -Properties pwdLastSet -ErrorAction Stop
if ($user.pwdLastSet -gt 0) {
$lastSet = [DateTime]::FromFileTime($user.pwdLastSet)
Write-Output "Password for user '$($user.SamAccountName)' was last set on: $($lastSet)"
} else {
Write-Warning "Password for user '$($user.SamAccountName)' has never been set or the value is unavailable in Active Directory."
}
}
catch {
# If Active Directory is not available or the user is not found there,
# attempt to query the local SAM
try {
$user = Get-LocalUser -Name $UserName -ErrorAction Stop
$sid = (Get-WmiObject -Class Win32_UserAccount -Filter "Name='$($user.Name)'").SID
$securityDescriptor = Get-Acl -Path "Registry::HKEY_LOCAL_MACHINE\SAM\SAM\Domains\Account\Users\$($sid)" -ErrorAction Stop
$passwordLastSetRaw = ($securityDescriptor.Sacl | Where-Object {$_.SecurityIdentifier -like "S-1-5-*" -and $_.ObjectAceType -eq "System Mandatory Label"}).ObjectSpecificAce.Ace.SubAuthority[0]
if ($passwordLastSetRaw -gt 0) {
$epochStart = [datetime]"01/01/1601"
$timeSpan = [TimeSpan]::FromTicks($passwordLastSetRaw * 100)
$lastSet = $epochStart + $timeSpan
Write-Output "Password for local user '$($user.Name)' was last set on: $($lastSet)"
} else {
Write-Warning "Could not determine the last password set time for local user '$($user.Name)'."
}
}
catch {
Write-Error "User '$($UserName)' not found on the local machine."
}
}
}
}
# Example usage:
# To find the last password set time for a specific user in Active Directory:
# Get-PasswordLastSet -UserName "domain\username"
# To find the last password set time for a local user:
# Get-PasswordLastSet -UserName "localusername"
# You can also pipe usernames to the function:
# "user1", "user2", "anotheruser" | Get-PasswordLastSet
No comments:
Post a Comment