C# 正在从ActiveDirectory检索用户帐户过期信息

C# 正在从ActiveDirectory检索用户帐户过期信息,c#,active-directory,C#,Active Directory,我正在尝试从帐户中检索过期日期 我试过了 DirectoryEntry user = new DirectoryEntry(iMem); var AccountExpiration = DateTime.FromFileTime((int)user.Properties["accountExpires"].Value); 它不工作,只给我错误“指定的强制转换无效” 当我使用 var AccountExpiration = user.Properties["accountExpires"];

我正在尝试从帐户中检索过期日期

我试过了

DirectoryEntry user = new DirectoryEntry(iMem);

var AccountExpiration = DateTime.FromFileTime((int)user.Properties["accountExpires"].Value);
它不工作,只给我错误“指定的强制转换无效”

当我使用

var AccountExpiration = user.Properties["accountExpires"];
返回我无法读取的com对象

使用windows powershell,效果很好,我不明白为什么这不起作用

这是我在powershell中使用的代码

$Expires = [datetime]::FromFileTime($tmpUser.accountExpires)

您可以使用
System.DirectoryServices.AccountManagement
命名空间来完成此任务。从
PrincipalContext
获取
UserPrincipal
后,可以检查
UserPrincipal.AccountExpirationDate
属性

PrincipalContext context = new PrincipalContext(ContextType.Domain);

UserPrincipal p = UserPrincipal.FindByIdentity(context, "Domain\\User Name");

if (p.AccountExpirationDate.HasValue)
{
    DateTime expiration = p.AccountExpirationDate.Value.ToLocalTime();
}
如果您想使用目录条目,请执行以下操作:

//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;
}
解析
accountExpires
值的另一种方法是使用反射:

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);
}
private静态长转换器LargeIntegerToLong(对象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);
返回(长)高位部分