- Which WSUS products to select for Windows 11? - Tue, Sep 26 2023
- Activate BitLocker with manage-bde, PowerShell, or WMI - Wed, Sep 20 2023
- Join Azure Active Directory with Windows 11 - Tue, Sep 12 2023
The PowerShell ActiveDirectory module allows you to read most of the information stored in AD objects. This includes the various password settings for user accounts, such as the expiry date and the time of the last change.
PowerShell is particularly useful for AD reporting because the graphical management tools are not entirely suitable for this task. After you install the Active Directory module, you can often retrieve many crucial configurations with a few simple commands.
Password management is certainly one of an Active Directory admin’s major tasks. For instance, you can display and change the current rules for users who are allowed to sign in without a password.
Reading user objects
The password expiry date and the time of the last password change are other important values of interest to admins. If you need the user list for multiple operations, you should first store it in a variable:
$Users = Get-ADUser -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} -Properties msDS-UserPasswordExpiryTimeComputed, PasswordLastSet, CannotChangePassword
This command determines all active user objects with a password expiry date. The ‑Properties parameter allows you to read the attributes of the expiry date, the date of the last password change, and the right to set a new password.
In large directories, you can restrict the query to specific domains or OUs with the help of the ‑SearchBase parameter (read Get-ADComputer – Display computers in OU or AD group with PowerShell).
Displaying the password expiry date
If you just want to generate a list of user names with their expiry dates and the times of the last password change, you can run this command:
$Users | select Name, @{Name="ExpiryDate";Expression={[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")}}, PasswordLastSet
List of user names with their expiry dates
Because the msDS-UserPasswordExpiryTimeComputed attribute doesn’t store the password expiry time in a human-readable format, the above command uses a calculated property and the function FromFileTime to convert it for output to a console.
Finding inactive accounts
Another interesting task is to find out whether particular users haven’t changed their password in a long time. Aside from the last logon date, this information could also hint to inactive accounts:
$maxPWAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge.Days
This command will retrieve the default setting for the maximum age of passwords. You can then add this value to the expiry date to determine whether the result is a date in the past:
foreach($u in $Users){ if( [datetime]::FromFileTime($u.'msDS-UserPasswordExpiryTimeComputed').addDays($maxPWAge) -lt (Get-Date)) { $u. DistinguishedName; $u.PasswordLastSet -replace "`n|`r","" } }
The users listed in the result hadn’t changed their password since the expiry date. If the calculated date is far in the past, the corresponding accounts are most likely inactive.
Users who cannot change their password
However, another explanation could be that those users are not allowed to change their password. The following code reveals whether the password of such users has expired and if an administrator should take a closer look:
foreach($u in $Users){ if($u.CannotChangePassword -eq $true -and [datetime]::FromFileTime($u."msDS-UserPasswordExpiryTimeComputed") -lt (Get-Date)) { $u. DistinguishedName } }
This call also examines whether the password expiry date lies in the past by comparing it to the current date returned by the Get-Date cmdlet.
You can also easily display user account password info from Command Prompt with:
net user usernamehere /domain | FIND /i “password”
The Column for Expiry date is blank both in your screen shot and when I run the same code.
One reason for this result might be, that users don’t have to change their passwords. So their accounts simply have no password expiration date. You can check by uing this command:
Get-ADUser -Filter ‘PasswordNeverExpires -eq $TRUE’ -Properties PasswordNeverExpires
Ok, my issue was “Password Does Not Expire” on the account I was testing with. When I tried it with a different account after verifying it’s password did expire it gave me “Sunday, December 31, 1600 7:00:00PM”. The output of Net user for the same user gives me “10/24/2016 7:23:11 am”