【问题标题】:How to get All attributes from an Active Directory user in C#如何在 C# 中从 Active Directory 用户获取所有属性
【发布时间】:2016-09-13 16:50:14
【问题描述】:

我一直在寻找使用 C# 代码的解决方案,该解决方案可以查询 Active Directory 用户注册到它的所有属性,无论它们是否具有 NULL 值。这些属性通过域服务器上 ADSI Edit 中用户属性中的属性编辑器选项卡可见。

AD user attributes in ADSI edit

我需要动态检索这些属性,这意味着我可能无法通过 MSDN 上的 ADSI 文档可靠地获取这些属性名称,因为并非所有这些属性都可能是特定于用户对象的: https://msdn.microsoft.com/en-us/library/ms675090(v=vs.85).aspx

这是我迄今为止尝试过的,但只得到了用户对象的一小部分属性:

  1. PS 命令Get-ADUser -Identity administrator -Properties:这检索了大部分属性,但不是几乎所有属性,我不知道在此命令期间调用了哪些 .NET 类和方法,因为TypeName = Microsoft.ActiveDirectory.Management.ADUser,它.NET 框架中不存在。如何在 PS 中查看 .NET 中使用的具体方法?

  2. C#调用这个方法:

    public bool GetUserAttributes(out List<string> userAttributes, string userName)
    {
        userAttributes = new List<string>();
        var valueReturn = false;
    
        try
        {
            const string pathNameDomain = "LDAP://test.local";
    
            var directoryEntry = new DirectoryEntry(pathNameDomain);
    
            var directorySearcher = new DirectorySearcher(directoryEntry)
            {
                Filter = "(&(objectClass=user)(sAMAccountName=" + userName + "))"
            };
    
            var searchResults = directorySearcher.FindAll();
    
            valueReturn = searchResults.Count > 0;
    
            StreamWriter writer = new StreamWriter("C:\\LDAPGETUSERADEXAMPLE.txt");
    
            foreach (SearchResult searchResult in searchResults)
            {
                foreach (var valueCollection in searchResult.Properties.PropertyNames)
                {
                    userAttributes.Add(valueCollection.ToString() + " = " + searchResult.Properties[valueCollection.ToString()][0].ToString());
    
                    try
                    {
                        writer.WriteLine("Bruger attribut:" + valueCollection);
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }
            }
    
  3. C#调用这个方法:

    public List<string> GetADUserAttributes()
    {
        string objectDn = "CN=testuser,OU=TEST,DC=test,DC=local";
    
        DirectoryEntry objRootDSE = new DirectoryEntry("LDAP://" + objectDn);
        List<string> attributes = new List<string>();
    
        foreach (string attribute in objRootDSE.Properties.PropertyNames)
        {
            attributes.Add(attribute);
        }
    
        return attributes;
    }
    

我应该怎么做才能不过滤掉我试图从中检索的用户对象的任何属性?

我知道默认情况下 Active Directory 只会显示默认属性或其中包含值的属性,我正在尝试克服此限制。

编辑 1:

我暂时推迟了具体问题。 我一直在尝试对这些方法中的哪一种在检索(读取操作)10.000 个名为“testuser”的个人 AD 用户的 SAM 帐户名称时最快的进行基准测试,我基准测试的方法如下:

  1. 完成时间:大约 500 毫秒:ADSI - system.directoryservices
  2. 完成时间:大约 2700 毫秒:主体 - 搜索器 system.directoryservices.accountmanagement
  3. 完成时间:关于 NOT WORKING :LDAP - System.DirectoryServices.Protocols
  4. 完成时间:大约 60 毫秒:SQL - System.Data.SqlClient

我正在从工作站查询用户信息 - 我正在查询的域中的 Windows 10 机器。工作站 (4 vcpu)、DC (2vpu) 和 DB (2vcpu) 服务器作为 Hyper V vm 运行。

【问题讨论】:

  • 我正在努力克服这个限制。 这不是限制。你想达到什么目的,即你为什么认为你需要这个?
  • @AnsgarWiechers :我需要获取属性名称(例如 AD 用户对象)的原因是因为我想为我的项目创建几乎相同的 AD 缓存。这个想法是在我的数据库的“用户”表中为每个属性名称创建一个列。然后我的前端网站可以从数据库而不是 AD 中检索这些缓存条目及其内容,我相信这会更快,因为它只需要快速 SQL 查询而不是 LDAP 查询。希望清除它,否则评论它。
  • 您的 LDAP 查询是否太慢?你对它们进行基准测试吗?如何?你试过caching LDAP proxy吗?
  • 确切地说,我目前没有使用 LDAP 查询,而是通过 system.directoryservices 类使用 ADSI,而不是专门使用 LDAP。但是我考虑过只通过 system.directoryservices.protocols.LDAP 使用 LDAP 查询。目前我还没有对哪个更快、ldap 或 sql 进行基准测试。也许如果我发现 LDAP/ADSI 和 SQL 一样快,我会让我的前端直接检索 AD 信息,这样我就不必同步 AD 和我的缓存 AD DB。我将尽快尝试创建基准。我将研究 LDAP 代理缓存。

标签: c# powershell active-directory attributes ldap


【解决方案1】:

任何类可以具有的所有属性都在 Active Directory 架构中定义

Use this 查询用户类别。然后只需调用 GetAllProperties 方法

var context = new DirectoryContext(DirectoryContextType.Forest, "amber.local");

using (var schema = System.DirectoryServices.ActiveDirectory.ActiveDirectorySchema.GetSchema(context))
{
    var userClass = schema.FindClass("user");

    foreach (ActiveDirectorySchemaProperty property in userClass.GetAllProperties())
    {
        // property.Name is what you're looking for
    }
}

但是,AD 架构可能因一种 AD 环境而异。例如,第三方程序或 Exchange Server 可以使用自定义属性扩展架构。这意味着具有预定义列的解决方案仅适用于特定环境。

【讨论】:

  • 强烈建议不要使用仅链接或链接为主的答案。请考虑引用来源,但将相关解决方案复制到您的答案中。
  • @Dimitry:谢谢,这似乎正是我想要的,我将测试解决方案并让您知道它是否有效:) 就架构仅限于特定环境而言,我正在尝试通过在安装时动态创建 DB 列而不是固定列来解决这个问题,这就是为什么我不能依赖关于属性的文档来满足我的需要。我确实意识到,如果架构因此发生变化,我将需要观察架构的变化并扩展我的数据库结构。然而,数据库的目的只是被前端网站作为缓存读取
  • 请注意,如果您要将 AD 数据存储在缓存中,则必须将其与 AD 同步。例如。有人更改用户的名字属性。换句话说,您的缓存应该与 AD 一起复制。这可以通过几种方法(DirSync、USN 轮询)来完成。其他解决方案是定期收集整个广告快照(例如广告中的所有用户)。
  • @Dimitry:我已经考虑过这个挑战,但不知道如何观察 AD 变化,但检查 USN 确实是需要的。你能提供一些提到的方法的参考吗?我计划进行实时复制,观察 USN 编号并将更改写入我的数据库,但是我还不知道确保非常快速的复制会产生多少开销,但我相信域控制器可以处理这个问题,因为它们一直在互相复制……
  • 不要使用更改通知技术。它根本行不通。另外,我建议您阅读 The .NET Developer's Guide to Directory Services Programming 一书。它包含有关如何使用目录同步跟踪更改的示例。复制过程非常快。域控制器将返回自上次复制以来发生的更改。您必须处理一些棘手的部分,例如。 G。在用户重命名\删除的情况下同步成员身份(重命名\删除 DB 中组成员身份中的用户,因为 LDAP 将返回您的专有名称而不是 SID)
猜你喜欢
  • 2021-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-30
  • 1970-01-01
  • 1970-01-01
  • 2020-02-01
  • 1970-01-01
相关资源
最近更新 更多