首页 > 解决方案 > 使用 Active Directory 组信息填充阵列

问题描述

我想为以下问题提供一些帮助。我想要一组关于我的 Active Directory 组的信息。

该数组将是一个二维数组,将有四列。

  1. ID --> 1,2,3,... 最大 ID 取决于组数
  2. 团体名称
  3. ID Parent --> 如果是父组,则添加第一个
  4. ID Child --> 如果是前一个 parent group 的 child,则添加 ID parents 的个数

如果有人可以给我一个提示,那将很有帮助。

我已经使用此代码获得了信息:

// Appel de la fonction GetDirectoryEntry
    DirectoryEntry entry = GetDirectoryEntry();

    // Création de l'objet de recherche
    DirectorySearcher search = new DirectorySearcher(entry);

    // Filtre de recherche pour récupérer tous les groupes de l'AD commençant par All Of *
    search.Filter = "(&(objectClass=group)(proxyAddresses=*)(name=All Of *))";

    SearchResultCollection results;
    // Results, contient tous les groupes commençant par All Of *
    results = search.FindAll();

标签: c#arraysactive-directory

解决方案


组是一种递归结构。因此,您需要使用成员属性进行递归迭代。成员可以是用户或其他组。所以我们需要过滤成员集合

相反,二维数组 y 创建了以下结构,允许存储父子关系:

class Group {
    public int Id { get; set; }
    public int? ParentId { get; set; }
    public string Name { get; set; }
    public List<Group> Members { get; set; }

    public Group() {
        Members = new List<Group>();
    }
}

搜索过程可以是这样的:

class Searcher {

    public string Filter { get; set; }
    public Searcher(string filter) {
        Filter = filter;
    }

    public List<Group> Search() {
        return Search(null, null);
    }

    protected List<Group> Search(string baseDn, int? parentId) {

        using (DirectoryEntry entryRoot = new DirectoryEntry("LDAP://" + baseDn)) {
            //We only iterate across groups (except root nodes)
            if (parentId.HasValue && !IsGroup(entryRoot))
                return null;

            using (DirectorySearcher search = new DirectorySearcher()) {
                search.Filter = $"(&(objectClass=group){Filter})";
                search.SearchRoot = entryRoot;

                SearchResultCollection results = search.FindAll();
                int i = 1;
                var groups = new List<Group>(results.Count);
                foreach (SearchResult result in results) {
                    using (DirectoryEntry entry = result.GetDirectoryEntry()) {
                        Group group = new Group {
                            Id = i,
                            Name = entry.Properties["cn"].Value.ToString(),
                            ParentId = parentId
                        };
                        var members = entry.Properties["member"];
                        foreach (string member in members) {
                            var subgroups = Search(member, i);
                            if (subgroups != null)
                                group.Members.AddRange(subgroups);
                        }
                        groups.Add(group);
                        i++;
                    }
                }
                return groups;
            }
        }
    }


    private bool IsGroup(DirectoryEntry entry) {
        return entry.Properties["objectClass"].Cast<string>().Any(x => x == "group");
    }

}

请注意 DirectorySearcher 和 DirectoryEntry 都是 IDisposable,为了简单起见,我没有处理它们

如果你真的需要一个数组,我认为递归迭代 List 很容易

您可以将 Searcher 初始化为:

Searcher searcher = new Searcher("(proxyAddresses=*)(name=All Of *)");
var groups = searcher.Search();

推荐阅读