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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18614810/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 12:45:00  来源:igfitidea点击:

How to convert Active Directory pwdLastSet to Date/Time

c#datetimeactive-directorylargenumber

提问by software is fun

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

The above method works great for most Active Directory properties except those that are related to date/time such as pwdLastSet, maxPwdAge, etc.

上述方法适用于大多数 Active Directory 属性,但与日期/时间相关的属性除外,例如 pwdLastSet、maxPwdAge 等。

My question is how to I get the pwdLastSet to a human readable datetime (like 8/13/2013 or August 13, 2013, etc)

我的问题是如何将 pwdLastSet 设置为人类可读的日期时间(例如 8/13/2013 或 2013 年 8 月 13 日等)

I've tries this but it threw exceptions

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

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;
}

I am using the following code to get the time as an Int64

我使用以下代码来获取时间作为 Int64

Int64 passwordLastSet = ConvertADSLargeIntegerToInt64(objResult.Properties["pwdLastSet"][0]);

Then I plan on using the DateTime(Int64) constructor to create a DateTime

然后我打算使用 DateTime(Int64) 构造函数来创建一个 DateTime

采纳答案by Matt Johnson-Pint

According to the MSDN documentation:

根据MSDN 文档

This value is stored as a large integer that represents the number of 100 nanosecond intervals since January 1, 1601 (UTC).

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

This aligns perfectly with DateTime.FromFileTimeUtc, as described here.

这与 完全一致DateTime.FromFileTimeUtc如此处所述

And I'm not sure why you feel the need to do the low level manipulation of the integer. I think you could just cast it.

而且我不确定为什么您觉得需要对整数进行低级操作。我想你可以投它。

So just do:

所以只需这样做:

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

回答by almaceleste

You can get the last password set date of a directory user in human readable form as easy as pie. To achieve this you can use nullable LastPasswordSetproperty of UserPrincipalclass from System.DirectoryServices.AccountManagementnamespace.

您可以像馅饼一样简单地以人类可读的形式获取目录用户的最后一次密码设置日期。为了实现这一点,您可以使用命名空间LastPasswordSetUserPrincipal类的可为空属性System.DirectoryServices.AccountManagement

If User must change password at next logonoption is checked then LastPasswordSetproperty returns nullvalue. Otherwise it returns the last date and time the password was set in type DateTime.

如果User must change password at next logon选项被选中,则LastPasswordSet属性返回null值。否则,它返回在 type 中设置密码的最后日期和时间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

MSDN:UserPrincipal
MSDN:LastPasswordSet