递归构造AD组织结构(Organizational Unit)的树形结构

我们知道,在AD中可以创建组织结构(Organizational Unit,以下称OU), 在OU中可以管理AD的组和用户。有时候需要向用户展示组织的树形结构,这里是一个常用的办法,就是使用递归的方式,从AD的根节点开始,递归查找子节点,然后构造一棵OU树。

操作AD,首先需要引用这两个程序集:

using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
然后定义一个类,作为OU树节点:

    public class OuTreeNode
    {
        public string Name { get; set; }
        public string Id { get; set; }
        private List<OuTreeNode> _children = new List<OuTreeNode>();

        public List<OuTreeNode> Children
        {
            get { return _children; }
            set { _children = value; }
        }
    }

这个类的名字是OuTreeNode,其中保存OU节点的基本信息,这里定义了OU的name,id,和子节点的列表。定义了这个类之后,我们就可以遍历AD的所有OU,然后将OU的基本信息保存在这个类中,最后构造出一棵树。以下是从根节点开始,递归查找OU的子节点来构造OU树的方法:

    public static OuTreeNode GetOuTree()
    {
        string domainName = string.Empty;
        OuTreeNode rootNode = null;
        using (Domain domain = Domain.GetCurrentDomain()) //为了简单,这里使用当前的域
        {
            domainName = domain.Name;
            rootNode = new OuTreeNode() { Name = domainName }; //使用域节点来构造OU树的根节点
            GetOuTreeRecursivly(rootNode, domain.GetDirectoryEntry()); //递归的查找子节点,构造OU树
        }
        return rootNode;
    }

    //递归构造树节点
    private static void GetOuTreeRecursivly(OuTreeNode parentNode, DirectoryEntry parentDirectoryEntry)
    {
        using (DirectorySearcher ds = new DirectorySearcher(parentDirectoryEntry))
        {
            ds.Filter = "(objectClass=organizationalunit)";
            ds.SearchScope = SearchScope.OneLevel; //仅查找当前OU下的子OU

            try
            {
                using (SearchResultCollection result = ds.FindAll())
                {
                    foreach (SearchResult entry in result)
                    {
                        string name = entry.GetDirectoryEntry().Properties["Name"].Value.ToString(); //获取Name属性
                        byte[] bytes = entry.GetDirectoryEntry().Properties["ObjectGuid"].Value as byte[];
                        Guid id = new Guid(bytes);
                        OuTreeNode node = new OuTreeNode() { Name = name, Id = id.ToString() }; //获取id属性
                        parentNode.Children.Add(node);
                        using (DirectoryEntry child = entry.GetDirectoryEntry())
                        {
                            GetOuTreeRecursivly(node, child);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }
    }

使用以上的两个方法就可以简单地构造出一棵OU树了,如果需要OU的其他属性信息,例如distinguishedName之类的,可以扩展OuTreeNode类,在构造树的时候,把需要的属性信息保存起来。

下面把构造好的OU树递归的打印出来:

    private static void print(OuTreeNode tree, int depth)
    {
        depth += 1;
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < depth; i++)
        {
            builder.Append("  ");
        }
        builder.Append(tree.Name);
        Console.WriteLine(builder.ToString());
        if (tree.Children.Count > 0)
        {
            foreach (OuTreeNode node in tree.Children)
            {
                print(node, depth);
            }
        }
    }

这种方法简单易懂,是常用的方法,但是缺点是访问AD次数过多,在OU多的情况下,会变慢。还有一种方法可以一次性查询出所有的OU,然后再构造OU树,请参见: 构造AD组织结构(Organizational Unit)的树形结构的另一个方法

你可能感兴趣的:(tree,ad,OU,组织结构树)