2021 Jun 20

Checking the *Real* Password Expiration Date

If you ever happened to have used ADAC for the users to set up their password policy to be different from the default for your domain, then you might have noticed the net user %username% /domain command will return not the expected value, as it checks the information quite differently. The script below will actually help to determine the real expiry date.

As reading from AD doesn't require the escalated privileges, it could be done with any account you like. For now, it will be using the command line, as it is more generic, faster, and just works. The GUI alternative is possible too, but it will be covered later.

For now, we can just have 2 lines of text (if you want to use credentials, then more of course, but as mentioned below, this is not really important for reading).

$user = Read-Host -Prompt "Username or part of it"
Get-ADUser -filter "samaccountname -like '*$user*' -and enabled -eq 'True' -and PasswordNeverExpires -eq 'False'" -Properties msDS-UserPasswordExpiryTimeComputed | Select-Object Name,sam*,@{n="Expiry Date";e={[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")}} | Sort-Object "Expiry Date"

What we have, is asking for input. You don't need to enter the colon or the space after - with the Read-Host -Prompt, PowerShell will take care about it for you. You can select to show you name, samaccountname and so on - whatever you prefer to see in the output. Sometimes, displayname is also fine. If this is a non-standard property - add it to the -Properties part of the command. The one we have there is what we exactly need - the expiry date. But originally it shows the information in so-called ticks, and that won't make much sense, so in the structure @{n="Expiry Date";e={[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")}} we are converting it to the human-readable view, which should be based on your system date settings.

With filtering, you should better use quotes, so you can search with wildcards, and have the matches included before the input, and after it. For example, if the input is "jd", then we will get the result for "jdoe", "abcjd", "abcjdoe" etc. Adding the -and PasswordNeverExpires -eq 'False' to the sctipt is optional - it will just skip the service accounts (which don't ususally have the expiration day), and they won't appear in the list with an empty field. But as far as we sort by the expiry date, they will be on the top, so you will see them separately from the rest. It's up to you, those scripts are rather adjustable.

Alternatively, you can add the function to your powershell profile. You can add something like this, just to ensure the user is entered:

function Get-PasswordExpiryDate {
  param(
        [Parameter(Mandatory)]
        [string]$user
    )
Get-ADUser -filter "samaccountname -like '*$user*' -and enabled -eq 'True' -and PasswordNeverExpires -eq 'False'" -Properties msDS-UserPasswordExpiryTimeComputed | Select-Object Name,sam*,@{n="Expiry Date";e={[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")}} | Sort-Object "Expiry Date"
}

Open a new instance or PowerShell - and you can use it either with Get-PasswordExpiryDate user, or just Get-PasswordExpiryDate - the command line will ask you to input the user afterwards. You can mention the expiry date of 1601 - it happens when the password has been never set:

They posted on the same topic

Trackback URL : https://dykhl.in/trackback/9

This post's comments feed