c# - 在不使用 ActiveDs 的情况下转换 ActiveDirectory pwdLastSet 属性

标签 c# active-directory

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

我找到了一个未记录的替代方案。测试它时,它要么完全开启,要么关闭 429.49673 秒。我不确定为什么,有人知道吗? (我测试的 20/49 人的延迟时间为 429.49673 秒)。

更新:看起来它发生在 LowPart 为负时。

代码:

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

引用资料:

  • 事件 DS 类型库
  • 系统目录服务

最佳答案

你需要像这样翻译 AD Long Integer,你不应该再需要 ActiveDs:

long pwdLastSet = ConvertADSLargeIntegerToInt64(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;
}

关于c# - 在不使用 ActiveDs 的情况下转换 ActiveDirectory pwdLastSet 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9592422/

相关文章:

C# 所有函数和方法抛出异常

c# - 在 .NET 中将域名转换为 LDAP 样式

powershell - 使用 Get-ADGroup 时隐藏错误

active-directory - 快速确定用户帐户是否为AD组成员的最佳方法?

c# - 如何在 asp.net 中创建模块?

c# - 流式运算符与延迟执行有何不同?

c# - 从事件目录中获取用户的密码

c# - 如何从 C# 中找到事件目录中的用户?

c# - asp.net ashx 请求 404

c# - 如何检查特定时间是否已过