How to Check Password Expiration Date in PowerShell

To check a password expiration date in Active Directory with PowerShell, read the computed msDS-UserPasswordExpiryTimeComputed attribute and convert it to a date:

Get-ADUser -Identity jsmith -Properties 'msDS-UserPasswordExpiryTimeComputed' |
    Select-Object -Property Name,
        @{ Name = 'PasswordExpires'; Expression = { [datetime]::FromFileTime($_.'msDS-UserPasswordExpiryTimeComputed') } }

Below I cover the attribute and the math behind it, an expiring-soon report, Microsoft 365 users, and local accounts.

My test PC isn’t on a domain, so I ran the date math and conversions on sample accounts. The AD and Microsoft Graph commands are shown as code.

How password expiration is calculated

AD stores when the password was last set, not when it expires. The expiry date is PasswordLastSet plus the maximum password age from the domain policy. Here’s that math for three sample accounts:

$today  = Get-Date -Date '2026-10-04'
$maxAge = New-TimeSpan -Days 42          # from Get-ADDefaultDomainPasswordPolicy
$users = @(
    [pscustomobject]@{ Name = 'jsmith';  PasswordLastSet = [datetime]'2026-08-28'; PasswordNeverExpires = $false }
    [pscustomobject]@{ Name = 'amiller'; PasswordLastSet = [datetime]'2026-09-30'; PasswordNeverExpires = $false }
    [pscustomobject]@{ Name = 'svc-sql'; PasswordLastSet = [datetime]'2026-01-12'; PasswordNeverExpires = $true }
)

foreach ($u in $users) {
    if ($u.PasswordNeverExpires) { $expires = 'Never'; $daysLeft = '-' }
    else {
        $expires  = ($u.PasswordLastSet + $maxAge).ToString('yyyy-MM-dd')
        $daysLeft = (($u.PasswordLastSet + $maxAge) - $today).Days
    }
    [pscustomobject]@{ Name = $u.Name; Expires = $expires; DaysLeft = $daysLeft }
}

Output:

Name    Expires    DaysLeft
----    -------    --------
jsmith  2026-10-09        5
amiller 2026-11-11       38
svc-sql Never             -
PowerShell calculate password expiration date
jsmith’s password expires in 5 days, and the service account never expires (PowerShell 7)

In your domain, read the real values with Get-ADUser -Properties PasswordLastSet, PasswordNeverExpires and (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge.

Why msDS-UserPasswordExpiryTimeComputed is better

The math above ignores fine-grained password policies, which can give some groups a different maximum age. The computed attribute already accounts for them, so I use it for real reports.

Convert msDS-UserPasswordExpiryTimeComputed to a date

The attribute is a Windows FILETIME number, in UTC. Two special values mean there’s no date: 0 (the password must be changed now) and the largest 64-bit number (it never expires). This helper handles both:

function ConvertFrom-ExpiryTime ([long]$Value) {
    if ($Value -eq 0 -or $Value -eq [long]::MaxValue) { return 'Never or must change now' }
    [datetime]::FromFileTimeUtc($Value).ToString('yyyy-MM-dd HH:mm') + ' UTC'
}

ConvertFrom-ExpiryTime 134392266000000000
ConvertFrom-ExpiryTime 9223372036854775807

Output:

2026-11-15 14:30 UTC
Never or must change now
PowerShell convert msDS-UserPasswordExpiryTimeComputed FILETIME
A FILETIME value and the never-expires value (Windows PowerShell 5.1)

[datetime]::FromFileTime() converts to your local time instead of UTC. Calling it on the never-expires value throws an error, which is why the check comes first.

Find users whose passwords expire soon

This report lists enabled users whose passwords expire in the next 14 days. It needs the ActiveDirectory module from RSAT:

$limit = (Get-Date).AddDays(14)
Get-ADUser -Filter 'Enabled -eq $true -and PasswordNeverExpires -eq $false' `
    -Properties 'msDS-UserPasswordExpiryTimeComputed', EmailAddress |
    Select-Object -Property Name, EmailAddress,
        @{ Name = 'Expires'; Expression = { [datetime]::FromFileTime($_.'msDS-UserPasswordExpiryTimeComputed') } } |
    Where-Object { $_.Expires -le $limit } |
    Sort-Object -Property Expires

Export the result to CSV or use it to send reminders.

Accounts with expired passwords often get locked, too, so see checking if an account is locked.

To go the other way and list accounts whose passwords haven’t changed in months, see how to find users with pwdLastSet older than 90 days.

Check password expiration in Microsoft 365

For cloud users, use the Microsoft Graph PowerShell SDK. The MSOnline and AzureAD modules are retired. Microsoft 365 passwords never expire by default, so check the domain policy first:

Connect-MgGraph -Scopes 'User.Read.All', 'Domain.Read.All'
Get-MgDomain -DomainId 'contoso.com' | Select-Object -Property Id, PasswordValidityPeriodInDays

Then read when each user last changed their password and whether expiration is turned off for them:

Get-MgUser -UserId 'jsmith@contoso.com' -Property DisplayName, LastPasswordChangeDateTime, PasswordPolicies |
    Select-Object -Property DisplayName, LastPasswordChangeDateTime, PasswordPolicies

PasswordPolicies shows DisablePasswordExpiration for users whose password never expires.

Check local account password expiration

On a standalone PC, the maximum password age comes from the local policy. net accounts shows it without admin rights:

net accounts | Where-Object { $_ -match 'password age' }

Output:

Minimum password age (days):                          0
Maximum password age (days):                          42
PowerShell net accounts maximum password age
Windows’ default 42-day maximum on my PC (PowerShell 7)

Then Get-LocalUser -Name jsmith | Select-Object Name, PasswordLastSet, PasswordExpires shows the expiry date for one account. To turn expiry off, see setting a local password to never expire.

Frequently Asked Questions

How do I check when a password expires in Active Directory?

Run Get-ADUser -Identity jsmith -Properties 'msDS-UserPasswordEx