如何将Active Directory的pwdLastSet转换为日期/时间

12
    public static string GetProperty(SearchResult searchResult, string PropertyName)
    {
        if (searchResult.Properties.Contains(PropertyName))
        {
            return searchResult.Properties[PropertyName][0].ToString();
        }
        else
        {
            return string.Empty;
        }
    }

对于大多数Active Directory属性,上述方法都非常有效,但对于与日期/时间有关的属性(如pwdLastSet、maxPwdAge等),则不适用。

我的问题是如何将pwdLastSet获取为可读的日期时间格式(例如8/13/2013或August 13, 2013等)

我尝试过这个方法,但它抛出了异常

public static Int64 ConvertADSLargeIntegerToInt64(object adsLargeInteger)
{
    var highPart = (Int32)adsLargeInteger.GetType().InvokeMember("HighPart", System.Reflection.BindingFlags.GetProperty, null, adsLargeInteger, null);
    var lowPart = (Int32)adsLargeInteger.GetType().InvokeMember("LowPart", System.Reflection.BindingFlags.GetProperty, null, adsLargeInteger, null);
    return highPart * ((Int64)UInt32.MaxValue + 1) + lowPart;
}

我正在使用以下代码将时间转换为Int64类型:

Int64 passwordLastSet = ConvertADSLargeIntegerToInt64(objResult.Properties["pwdLastSet"][0]);
然后我打算使用DateTime(Int64)构造函数创建一个DateTime。
2个回答

15

根据MSDN文档

该值存储为一个大整数,它代表自1601年1月1日(UTC)以来的100纳秒间隔数。

这与DateTime.FromFileTimeUtc完美对齐,如此描述

我不确定您为什么需要进行低级别的整数操作。 我认为您可以直接将其强制转换。

所以只需执行以下操作:

long value = (long)objResult.Properties["pwdLastSet"][0];
DateTime pwdLastSet = DateTime.FromFileTimeUtc(value);

2
你可以轻松获取目录用户的最后设置密码日期以人类可读的形式呈现。要实现这一点,您可以使用来自System.DirectoryServices.AccountManagement命名空间的UserPrincipal类的可空LastPasswordSet属性。
如果选中“用户下次登录时必须更改密码”选项,则LastPasswordSet属性返回null值。否则,它将返回密码上次设置的日期和时间,类型为DateTime。
using(PrincipalContext context = new PrincipalContext(ContextType.Domain))
{
    UserPrincipal user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, Username);
    //? - to mark DateTime type as nullable
    DateTime? pwdLastSet = (DateTime?)user.LastPasswordSet;
    ...
}

MSDN:UserPrincipal
MSDN:LastPasswordSet


1
这是一种更简单的解决方案,可能比使用DirectorySearcher更受欢迎。 - Kostia Shiian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接