I'm trying to retrieve the expiration date from accounts.
I've tried
DirectoryEntry user = new DirectoryEntry(iMem);
var AccountExpiration = DateTime.FromFileTime((int)user.Properties["accountExpires"].Value);
it doesn't work, only gives me the error "Specified cast is not valid".
When I use
var AccountExpiration = user.Properties["accountExpires"];
returns a com object, which I'm unable to read.
Using windows powershell, works fine, I don't get why this wont work...
this is the code I use in powershell
$Expires = [datetime]::FromFileTime($tmpUser.accountExpires)
Navigate to Reports> User Reports > Account expired users.
A really easy way to tell when an AD user account password expires is to use the Net User command. This command is part of the “net commands” that allows you to add, remove, or modify the user account on a computer.
If a synced directory user account is expired (past the account expiration date) in Active Directory (AD), the user will continue to have a status of "Active" in Duo when the next directory sync occurs. This does not disable the user in Duo, so they continue to consume a license.
In Active Directory, the account will not be locked if a user's password expires. Instead, the user will be prompted to change the password, and the new one must follow the password rules established by the organization based on its security policies.
You can use the System.DirectoryServices.AccountManagement
namespace to accomplish this task. Once you get a UserPrincipal
from a PrincipalContext
, you can inspect the UserPrincipal.AccountExpirationDate
property.
PrincipalContext context = new PrincipalContext(ContextType.Domain);
UserPrincipal p = UserPrincipal.FindByIdentity(context, "Domain\\User Name");
if (p.AccountExpirationDate.HasValue)
{
DateTime expiration = p.AccountExpirationDate.Value.ToLocalTime();
}
If you do want to use DirectoryEntry
, do this:
//assume 'user' is DirectoryEntry representing user to check
DateTime expires = DateTime.FromFileTime(GetInt64(user, "accountExpires"));
private Int64 GetInt64(DirectoryEntry entry, string attr)
{
//we will use the marshaling behavior of the searcher
DirectorySearcher ds = new DirectorySearcher(
entry,
String.Format("({0}=*)", attr),
new string[] { attr },
SearchScope.Base
);
SearchResult sr = ds.FindOne();
if (sr != null)
{
if (sr.Properties.Contains(attr))
{
return (Int64)sr.Properties[attr][0];
}
}
return -1;
}
Another way of parsing the accountExpires
value is using reflection:
private static long ConvertLargeIntegerToLong(object largeInteger)
{
Type type = largeInteger.GetType();
int highPart = (int)type.InvokeMember("HighPart", BindingFlags.GetProperty, null, largeInteger, null);
int lowPart = (int)type.InvokeMember("LowPart", BindingFlags.GetProperty | BindingFlags.Public, null, largeInteger, null);
return (long)highPart <<32 | (uint)lowPart;
}
object accountExpires = DirectoryEntryHelper.GetAdObjectProperty(directoryEntry, "accountExpires");
var asLong = ConvertLargeIntegerToLong(accountExpires);
if (asLong == long.MaxValue || asLong <= 0 || DateTime.MaxValue.ToFileTime() <= asLong)
{
return DateTime.MaxValue;
}
else
{
return DateTime.FromFileTimeUtc(asLong);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With