The Get-ADUser cmdlet with AccountExpirationDate property is fundamental for managing expired user accounts in Active Directory. Whether you need to export expired AD users PowerShell reports for compliance, create an account expiration report PowerShell script for auditing, or generate expired accounts CSV files for cleanup operations, this cmdlet provides essential data. However, filtering expired users, handling date comparisons, and performing PowerShell expired user export across multiple domains requires careful scripting and proper date manipulation.
The PasswordNeverExpires property determines whether a user's password follows the domain's policy. Setting it to False ensures the password will expire according to the domain's policy. In rare cases like service accounts, hardcoded credentials, or legacy apps that may break if passwords change, you may need to set PasswordNeverExpires to True so the password never expires.
Steps to obtain the Account Expired Users report using PowerShell:
$OutFile = 'C:\Scripts\AccountExpiredUsers.csv' # your output file
Get-ADUser -Filter * -Properties Name, Enabled, AccountExpirationDate, LastLogonDate | ? {($_.AccountExpirationDate -NE $NULL -AND $_.AccountExpirationDate -LT (Get-Date)) } | foreach {Add-Content -path $OutFile "$($_.Name),$($_.Enabled)"}
Finding expired AD users with ADManager Plus:
Generate a basic Get-ADUser expired accounts report showing all expired users.
Get-ADUser -Filter {AccountExpirationDate -lt (Get-Date)} -Properties AccountExpirationDate | Select Name,SamAccountName,AccountExpirationDate | Export-CSV "C:\ExpiredAccounts.csv" -NoTypeInformation
This command identifies all users with accounts that have passed their expiration date.
Create a PowerShell list expired users script for recently expired accounts.
$30DaysAgo = (Get-Date).AddDays(-30)
Get-ADUser -Filter {AccountExpirationDate -lt (Get-Date) -and AccountExpirationDate -gt $30DaysAgo} -Properties AccountExpirationDate,Department | Export-CSV "C:\RecentlyExpired.csv" -NoTypeInformation
This account expiration report PowerShell helps identify recently expired accounts for potential reactivation.
Create a proactive PowerShell AccountExpirationDate query for upcoming expirations.
$NextWeek = (Get-Date).AddDays(7)
Get-ADUser -Filter {AccountExpirationDate -gt (Get-Date) -and AccountExpirationDate -lt $NextWeek} -Properties AccountExpirationDate,EmailAddress | Export-CSV "C:\ExpiringNext7Days.csv" -NoTypeInformation
This helps prevent service disruptions by identifying soon-to-expire accounts.
| Parameters | Description |
|---|---|
| -Filter | Essential for comparing AccountExpirationDate with current or specific dates |
| -SearchBase | Specifies the OU or container to search for expired accounts |
| -SearchScope | Controls search depth when looking for expired users |
| -Properties | Must include AccountExpirationDate as it's not returned by default |
| -LDAPFilter | Enables complex LDAP queries for sophisticated expiration filtering |
| -ResultPageSize | Manages pagination for large expired user queries |
| -Credential | Provides alternate credentials for accessing expired user information |
Get-ADUser -Filter {AccountExpirationDate -like "*" -and AccountExpirationDate -lt (Get-Date)}
Get-ADUser -Filter * -Properties AccountExpirationDate | Where {$_.AccountExpirationDate -ne $null -and $_.AccountExpirationDate -lt (Get-Date)}
Get-ADUser -Filter {AccountExpirationDate -lt (Get-Date)} -Properties AccountExpirationDate |
Select Name,@{N='ExpirationDate';E={$_.AccountExpirationDate.ToString('yyyy-MM-dd')}} |
Export-CSV "C:\ExpiredUsers.csv" -NoTypeInformation
Get-ADUser -Filter {AccountExpirationDate -lt (Get-Date)} # Correct
# Not: Get-ADUser -Filter "AccountExpirationDate -lt (Get-Date)" # Incorrect
AccountExpirationDate and PasswordExpiration serve different purposes:
To get both expiration dates:
Get-ADUser -Identity "username" -Properties AccountExpirationDate, PasswordLastSet, PasswordNeverExpires |
Select Name, AccountExpirationDate, @{N='PasswordExpiration';E={if($_.PasswordNeverExpires) {'Never'} else {$_.PasswordLastSet.AddDays(90)}}}
Common causes and solutions:
To filter out null values explicitly
Get-ADUser -Filter * -Properties AccountExpirationDate |
Where-Object {$_.AccountExpirationDate -ne $null -and $_.AccountExpirationDate -lt (Get-Date)}
Correct syntax:
Get-ADUser -Filter {AccountExpirationDate -lt (Get-Date)}
Incorrect syntax:
Get-ADUser -Filter "AccountExpirationDate -lt (Get-Date)"
When Active Directory Users and Computers shows "Never", the AccountExpirationDate is actually null:
To find users with no expiration date:
Get-ADUser -Filter * -Properties AccountExpirationDate |
Where-Object {$_.AccountExpirationDate -eq $null} |
Select Name, SamAccountName, @{N='ExpirationStatus';E={'Never Expires'}}
To set expiration date for users without one:
Get-ADUser -Filter {AccountExpirationDate -notlike "*"} |
Set-ADUser -AccountExpirationDate (Get-Date).AddDays(90)
Use date arithmetic to calculate remaining days:
Get-ADUser -Filter {AccountExpirationDate -like "*"} -Properties AccountExpirationDate |
Select Name, AccountExpirationDate, @{N='DaysUntilExpiration';E={
if($_.AccountExpirationDate -gt (Get-Date)) {
($_.AccountExpirationDate - (Get-Date)).Days
} else {
"Already Expired"
}
}} | Sort-Object DaysUntilExpiration
Yes, you can extend expiration dates for multiple accounts.
To extend all expiring accounts by 30 days:
$NextMonth = (Get-Date).AddDays(30)
Get-ADUser -Filter {AccountExpirationDate -lt $NextMonth -and AccountExpirationDate -gt (Get-Date)} -Properties AccountExpirationDate |
ForEach-Object {
Set-ADUser $_ -AccountExpirationDate $_.AccountExpirationDate.AddDays(30)
Write-Host "Extended $($_.Name) until $($_.AccountExpirationDate.AddDays(30))"
}