๐ Recipe ยท Entra ID & Identity
Check When a Microsoft 365 User's Password Expires
Determine the password expiration date for any Microsoft 365 user and proactively notify them before lockout
Complexity
Beginner
Impact
user-support + security + password-policy + entra-id + read-only
Context
Why This Matters
End users frequently ask IT when they need to change their password to avoid being locked out. In Microsoft 365, password expiration behavior depends on the tenant's password policy and per-user settings. Some users may have PasswordNeverExpires enabled, while others inherit the tenant default (commonly 90 days or disabled entirely in modern tenants following Microsoft's recommendation).
This recipe shows how to calculate a user's password expiration date by combining the last password change timestamp with the tenant password validity period. It is useful for:
- Responding to individual user questions about upcoming expiration
- Proactively warning users before their password expires
- Auditing accounts whose passwords never expire (a security concern)
- Troubleshooting authentication failures suspected to be caused by expired credentials
Expected Outcomes
After completing this recipe you will have:
- The exact date and time of the user's last password change
- The tenant's password validity period (in days)
- A calculated password expiration date for the user
- Confirmation of whether the user's password is set to never expire
- The number of days remaining until expiration
Risks & Considerations
Considerations
- Microsoft's current guidance is to disable password expiration in favor of MFA and risk-based conditional access. Verify your organization's policy before recommending any expiration scheme.
- The
lastPasswordChangeDateTimeproperty only updates when the user actually changes their password โ it does not reflect forced resets in all cases. Validate against sign-in logs if precision matters. - Per-user
PasswordNeverExpiresoverrides the tenant policy. A user with this flag set will never receive an expiration warning even if the tenant policy enforces rotation. - The tenant-wide password validity period is stored on the domain object (
passwordValidityPeriodInDays), not the user. A value of2147483647(Int32.MaxValue) indicates "never expires" at the tenant level. - Do not communicate expected expiration dates to users as a guarantee โ admins or policy changes can force a reset at any time.
Required Permissions
| Permission | Why It's Needed |
|---|---|
| User.Read.All | Read user properties including lastPasswordChangeDateTime and passwordPolicies |
| Domain.Read.All | Read the tenant's password validity period from the default domain |
| Directory.Read.All | Alternative broader scope if User.Read.All + Domain.Read.All are not available |
The fastest way to get this done: just ask Dex. Copy the prompt below and paste it into your Dex conversation.
For IT Admins
Paste into Dex Pro
For End Users
How an employee would ask Dex for help
Check Password Expiration via Microsoft 365 Admin Center
The admin center does not show an exact expiration date, but you can determine the last password change and the tenant policy and calculate it yourself.
Step 1: Find the user's last password change
- Sign in to the Microsoft 365 Admin Center as a Global Admin or User Admin.
- Navigate to .
- Click the display name of the target user to open their profile pane.
- Select the Account tab.
- Note the value under Password last changed.
Step 2: Check the tenant password policy
- In the admin center, go to .
- Click Password expiration policy.
- If "Set user passwords to expire after a number of days" is unchecked, passwords never expire at the tenant level โ stop here.
- If checked, note the value in Days before passwords expire (e.g. 90).
Step 3: Calculate expiration
Expiration date = Password last changed + Days before passwords expire.
Step 4: Verify the user is not exempt
- Back on the user's profile, check the Account tab for "Password never expires". If it appears, the user is exempt regardless of tenant policy.
Check Password Expiration via Microsoft Graph API
Combine two Graph calls: one to read the user's last password change and policy flags, and one to read the tenant-wide validity period from the initial domain.
1. Get the user's password metadata
GET https://graph.microsoft.com/v1.0/users/{userPrincipalName}?$select=id,userPrincipalName,lastPasswordChangeDateTime,passwordPoliciesExample response:
{
"id": "a1b2c3d4-...",
"userPrincipalName": "alice@contoso.com",
"lastPasswordChangeDateTime": "2024-08-15T14:22:10Z",
"passwordPolicies": "None"
}If passwordPolicies contains DisablePasswordExpiration, the user's password never expires.
2. Get the tenant password validity period
GET https://graph.microsoft.com/v1.0/domains?$select=id,isDefault,passwordValidityPeriodInDays,passwordNotificationWindowInDaysExample response (default domain object):
{
"id": "contoso.onmicrosoft.com",
"isDefault": true,
"passwordValidityPeriodInDays": 90,
"passwordNotificationWindowInDays": 14
}A value of 2147483647 means passwords never expire at the tenant level.
3. Calculate
expirationDateTime = lastPasswordChangeDateTime + passwordValidityPeriodInDays
Required headers
Authorization: Bearer {access_token}Accept: application/json
Check Password Expiration via PowerShell
The Microsoft Graph PowerShell SDK makes this straightforward. Install it once with Install-Module Microsoft.Graph -Scope CurrentUser.
Connect
Connect-MgGraph -Scopes "User.Read.All","Domain.Read.All"Read user properties
$user = Get-MgUser -UserId "alice@contoso.com" -Property Id,UserPrincipalName,LastPasswordChangeDateTime,PasswordPolicies
$user | Select-Object UserPrincipalName,LastPasswordChangeDateTime,PasswordPoliciesRead tenant password policy
$domain = Get-MgDomain | Where-Object IsDefault -eq $true
$validityDays = $domain.PasswordValidityPeriodInDaysCalculate expiration
if ($user.PasswordPolicies -match "DisablePasswordExpiration") {
Write-Host "Password never expires for this user."
} elseif ($validityDays -eq 2147483647) {
Write-Host "Tenant policy: passwords never expire."
} else {
$expires = $user.LastPasswordChangeDateTime.AddDays($validityDays)
$daysLeft = ($expires - (Get-Date)).Days
Write-Host "Expires on $expires ($daysLeft days remaining)"
}The downloadable script below wraps this logic with parameter validation, error handling, and tabular output.
Next steps