To be pedantic:
You need to check for special cases before converting to DateTime - for example pwdLastSet can be zero, so you should check this before attempting to convert.
pwdLastSet
is stored as UTC - so that converting to local time using DateTime.FromFileTime
might return an ambiguous time.
So it would be better to use DateTime.FromFileTimeUtc
and compare with DateTime.UtcNow
.
Depending on exactly what you want to achieve, you may also want to check the userAccountControl flags - something like the following (untested):
[Flags]
private enum AdsUserFlags
{
Script = 0x1,
AccountDisabled = 0x2,
HomeDirectoryRequired = 0x8,
AccountLockedOut = 0x10,
PasswordNotRequired = 0x20,
PasswordCannotChange = 0x40,
EncryptedTextPasswordAllowed = 0x80,
TempDuplicateAccount = 0x100,
NormalAccount = 0x200,
InterDomainTrustAccount = 0x800,
WorkstationTrustAccount = 0x1000,
ServerTrustAccount = 0x2000,
PasswordDoesNotExpire = 0x10000,
MnsLogonAccount = 0x20000,
SmartCardRequired = 0x40000,
TrustedForDelegation = 0x80000,
AccountNotDelegated = 0x100000,
UseDesKeyOnly = 0x200000,
DontRequirePreauth = 0x400000,
PasswordExpired = 0x800000,
TrustedToAuthenticateForDelegation = 0x1000000,
NoAuthDataRequired = 0x2000000
}
...
AdsUserFlags userAccountControl = (AdsUserFlags)result.Properties["userAccountControl"][0];
long lastReset = (long)result.Properties["PwdLastSet"][0];
if (lastReset == 0L)
{
if ((userAccountControl & AdsUserFlags.PasswordDoesNotExpire) == 0)
{
// ... user must set password at next login
}
else
{
// ... presumably password has never been reset
}
}
else
{
DateTime lastResetUtc = DateTime.FromFileTimeUtc(lastReset);
// ... etc - compare with DateTime.UtcNow
}