在不使用 ActiveD 的情况下投射 ActiveDirectory pwdLastSet 属性

时间:2022-11-20
本文介绍了在不使用 ActiveD 的情况下投射 ActiveDirectory pwdLastSet 属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

好的.所以我试图找到一种方法来避免在我的项目中包含 ActiveD,因为我无法让 dll 显示在安装程序中.拥有它的唯一原因是将 pwdLastSet 转换为 LongInteger.

Ok. So I'm trying to find a way to avoid including ActiveDs in my project because I'm having trouble getting the dll to show up in the installer. The only reason to have it is to cast the pwdLastSet as a LongInteger.

我找到了一个无证替代品.测试它时,它要么完全开启,要么关闭 429.49673 秒.我不知道为什么,有人知道吗?(我测试的 20/49 人的时间为 429.49673 秒).

I found an undocumented alternative. When testing it, it is either dead on or 429.49673 seconds off. I'm not sure why, does anybody have any idea? (20/49 people that i tested are 429.49673 seconds off).

UPDATE:看起来像是 LowPart 为负时发生的.

UPDATE: It looks like it happens when the LowPart is negative.

代码:

    private static string DateTest() {
        return DateTest(Environment.UserName);
    }
    private static string DateTest(string userName) {
        userName = userName.Trim();
        DateTime hacked, normal;
        using (DirectorySearcher ds = new DirectorySearcher()) {
            ds.SearchScope = SearchScope.Subtree;
            ds.PropertiesToLoad.Add("distinguishedName");
            ds.PropertiesToLoad.Add("pwdLastSet");
            ds.PageSize = 1;
            ds.ServerPageTimeLimit = TimeSpan.FromSeconds(2);
            ds.Filter = string.Format("(&(objectCategory=user)(sAMAccountName={0}))", userName);

            SearchResult sr = ds.FindOne();
            hacked = DateTime.FromFileTime((long)sr.Properties["pwdLastSet"][0]);

            using (DirectoryEntry user = sr.GetDirectoryEntry()) {
                var value = user.Properties["pwdLastSet"][0] as ActiveDs.LargeInteger;
                var longValue = (((long)value.HighPart) << 32) + (long)value.LowPart;
                normal = DateTime.FromFileTime(longValue);
            }
        }

        return string.Format("{3} - Difference: {0:0.0} seconds. Established Method returns: {1}. Hacked method returns: {2}",
            hacked.Subtract(normal).TotalSeconds, normal, hacked, userName);
    }
}

参考资料:

  • Active DS 类型库
  • System.DirectoryServices

推荐答案

你需要像这样翻译 AD Long Integer 并且你不再需要 ActiveDs:

You'll need to translate the AD Long Integer like this and you shouldn't need ActiveDs anymore:

long pwdLastSet = CovertADSLargeIntegerToInt64(oUser.Properties["pwdLastSet"].Value);

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

这篇关于在不使用 ActiveD 的情况下投射 ActiveDirectory pwdLastSet 属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一篇:我什么时候需要域名和域容器来创建 PrincipalContext? 下一篇:如何将 Active Directory pwdLastSet 转换为日期/时间

相关文章

最新文章