I am using Powershell to determine the password expiry date for domain accounts. I have used the following command to get this information:
Get-ADUser -Filter {SamAccountName -eq "<username>"} -Properties "DisplayName" , "msDS-UserPasswordExpiryTimeComputed"
I then covert this value to a meaningful date by using:
[datetime]::FromFileTime(<computed filetime from above command>)
This works fine for all the domains I use, except one. In that domain I get a value of 9223372036854775807
as the msDS-UserPasswordExpiryTimeComputed
. I am not able to use the FromFileTime
function to convert this number into a date. It throws as error. Upon researching I have found that this number means that the password is set not to expire. However, I know that passwords do expire in this domain. Further, the PasswordNeverExpires
property from the Get-ADUser
cmdlet shows as False
.
How can I get 9223372036854775807
from msDS-UserPasswordExpiryTimeComputed
attribute and get a False
from the PasswordNeverExpires
property? This seems like a contradiction. What am I missing? Are there other situations when msDS-UserPasswordExpiryTimeComputed
could be 9223372036854775807
too? Thanks.
The documentation lists several conditions in which msDS-UserPasswordExpiryTimeComputed
returns 9223372036854775807
aka 0x7fffffffffffffff
aka [int64]::MaxValue
(TO
refers to a given target object):
If any of the
ADS_UF_SMARTCARD_REQUIRED
,ADS_UF_DONT_EXPIRE_PASSWD
,ADS_UF_WORKSTATION_TRUST_ACCOUNT
,ADS_UF_SERVER_TRUST_ACCOUNT
,ADS_UF_INTERDOMAIN_TRUST_ACCOUNT
bits is set inTO!userAccountControl
, thenTO!msDS-UserPasswordExpiryTimeComputed
=0x7FFFFFFFFFFFFFFF
.
[...]
Else, ifEffective-MaximumPasswordAge = 0x8000000000000000
, thenTO!msDS-UserPasswordExpiryTimeComputed
=0x7FFFFFFFFFFFFFFF
(whereEffective-MaximumPasswordAge
is defined in [MS-SAMR] section 3.1.1.5).
Without knowing all the details, it seems that the msDS-UserPasswordExpiryTimeComputed
property returning 0x7FFFFFFFFFFFFFFF
indicates that there is effectively no password expiration, for a variety of reasons, only one of which is PasswordNeverExpires
being set to $True
.
Therefore, you could filter out such values:
Get-ADUser -Filter "SamAccountName -eq '<username>'" `
-Properties DisplayName, msDS-UserPasswordExpiryTimeComputed | #`
Where { $_.msDS-UserPasswordExpiryTimeComputed -ne 0x7FFFFFFFFFFFFFFF } | ForEach {
# ...
$dt = [datetime]::FromFileTime($_.msDS-UserPasswordExpiryTimeComputed)
}
It may even be possible to incorporate the test for 0x7FFFFFFFFFFFFFFF
into the -Filter
argument.
As an aside: Note that I've used a string rather than a script block ({ ... }
) as the -Filter
argument, because using script blocks is best avoided.