使用C#嵌套的AD用户组枚举 [英] Enumeration of nested AD user groups using C#

查看:225
本文介绍了使用C#嵌套的AD用户组枚举的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经写了一些code,获取组和嵌套组的所有用户。我还希望确保循环未发生,如果组成员资格由具有第一组的最后一组的成员引起的一环。

在code我写的作品确定,但有一点慢。

这是我第一次尝试做AD查找。

可能有人来看看,并告诉我,如果code看起来不错的好坏编码(或更糟),或者我已经约了错误的方式?

 使用系统;
使用System.Collections.Generic;
使用System.Text;
使用System.DirectoryServices中;
使用System.IO;

命名空间Tester3
{
    类Program3
    {
        公共静态列表<字符串> appGroupList =新的名单,其中,串>();
        公共静态列表<字符串>用户列表=新的名单,其中,串>();
        公共静态列表<字符串> GROUPLIST =新的名单,其中,串>();
        公共静态列表<字符串> groupChecked =新的名单,其中,串>();

        静态无效的主要(字串[] args)
        {
            //创建输出文件
            StreamWriter的OUTPUTFILE =新的StreamWriter(output.txt的,假);

            appGroupList.Add(GLB-SBCCitrixHelpdesk-DL);
            appGroupList.Add(SBC_UKBSAVIA001_PROD_ROL_Siebel);

            的foreach(在appGroupList串appGroup)
            {
                字符串appGroupCN = GetCN(appGroup);

                GetMembers(appGroupCN);

                groupChecked.Clear();
            }

            的foreach(在用户列表字符串项)
            {
                Console.WriteLine(项目);
                outputfile.WriteLine(项目);
            }

            outputfile.Flush();
            outputfile.Close();
            到Console.ReadLine();
        }

        私人静态字符串GetCN(弦乐群)
        {
            字符串groupCN =的String.Empty;

            尝试
            {
                使用(DirectorySearcher从搜索=新DirectorySearcher从())
                {
                    sea​​rch.Filter =(及(CN =+基+)(objectClass的=基团));
                    sea​​rch.PropertiesToLoad.Add(CN);
                    信息搜索结果的结果= search.FindOne();

                    如果(结果!= NULL)
                    {
                        groupCN = result.Properties [Active Directory路径] [0]的ToString();
                        groupCN = groupCN.Replace(LDAP://,);
                    }

                    返回groupCN;
                }
            }
            赶上(例外)
            {
                返回groupCN;
            }
        }

        使用群体的充分CN公共静态无效GetMembers(弦乐群)//获取成员
        {
            //检查组已检查
            如果(groupChecked.Contains(组))
            {
                返回;
            }

            //添加组groupChecked名单
            groupChecked.Add(组);

            尝试
            {
                //连接到组对象
                使用(的DirectoryEntry groupObject =新的DirectoryEntry(LDAP://+组))
                {
                    //获取组对象的成员
                    PropertyValueCollection COL = groupObject.Properties [成员]作为PropertyValueCollection;

                    //循环遍历每个成员
                    的foreach(在山坳对象的成员)
                    {
                        //连接到成员对象
                        使用(的DirectoryEntry memberObject =新的DirectoryEntry(LDAP://+成员))
                        {
                            //获取类成员对象
                            字符串成员类= memberObject.Properties [对象类] [1]的ToString();
                            字符串memberCN = memberObject.Properties [名称] [0]的ToString();

                            如果(!groupChecked.Contains(member.ToString()))
                            {
                                如果(memberClass.ToLower()==组)
                                {
                                    GetMembers(member.ToString());
                                }
                                其他
                                {
                                    userList.Add(memberCN);
                                }
                            }
                            其他
                            {
                                如果(memberClass.ToLower()!=组)
                                {
                                    userList.Add(memberCN);
                                }
                            }
                        }
                    }
                }
            }
            赶上(例外)
            {
            }
        }
    }
}
 

解决方案

如果你在.NET 3.5及以上,你应该看看 System.DirectoryServices.AccountManagement (S.DS.AM)命名空间。阅读所有关于它的:

基本上,你可以定义域范围内,并很容易地找到在AD用户和/或组:

  //设置站点范围内
PrincipalContext CTX =新PrincipalContext(ContextType.Domain);

//查找用户
UserPrincipal用户= UserPrincipal.FindByIdentity(CTXSomeUserName);

如果(用户!= NULL)
{
   //获取用户的组成员
   的foreach(在me.GetGroups校长校长())
   {
       GroupPrincipal GP =(本金为GroupPrincipal);

       如果(GP!= NULL)
       {
           //做一些跟团
       }
   }
}
 

新S.DS.AM使得它可以很容易地玩弄用户和组AD。以 .GetGroups()的调用还可以处理嵌套组成员的所有问题等等为你 - !没有必要处理这个麻烦了。

I've written some code that gets all users of groups and nested groups. I also wanted to make sure that looping did not happen if the group membership caused a loop by having the first group a member of the last group.

The code I wrote works OK but is a little slow.

This is the first time I've tried to do AD look-ups.

Could someone take a look and tell me if the code looks OK or bad-coding (or worse), or I've gone about it the wrong way?

using System;
using System.Collections.Generic;
using System.Text;
using System.DirectoryServices;
using System.IO;

namespace Tester3
{
    class Program3
    {
        public static List<string> appGroupList = new List<string>();        
        public static List<string> userList = new List<string>();
        public static List<string> groupList = new List<string>();
        public static List<string> groupChecked = new List<string>();

        static void Main(string[] args)
        {
            // Create Output File
            StreamWriter outputfile = new StreamWriter("output.txt", false);

            appGroupList.Add("GLB-SBCCitrixHelpdesk-DL");
            appGroupList.Add("SBC_UKBSAVIA001_PROD_ROL_Siebel");

            foreach (string appGroup in appGroupList)
            {
                string appGroupCN = GetCN(appGroup);

                GetMembers(appGroupCN);

                groupChecked.Clear();
            }

            foreach (string item in userList)
            {
                Console.WriteLine(item);
                outputfile.WriteLine(item);
            }

            outputfile.Flush();
            outputfile.Close();
            Console.ReadLine();
        }

        private static string GetCN(string group)
        {
            string groupCN = string.Empty;

            try
            {
                using (DirectorySearcher search = new DirectorySearcher())
                {
                    search.Filter = "(&(cn=" + group + ")(objectClass=group))";
                    search.PropertiesToLoad.Add("CN");
                    SearchResult result = search.FindOne();

                    if (result != null)
                    {
                        groupCN = result.Properties["adsPath"][0].ToString();
                        groupCN = groupCN.Replace("LDAP://", "");
                    }

                    return groupCN;
                }
            }
            catch (Exception)
            {
                return groupCN;
            }
        }

        public static void GetMembers(string group) // get members using the groups full cn 
        {
            // Check if group has already been checked
            if (groupChecked.Contains(group))
            {
                return;
            }

            // Add group to groupChecked list
            groupChecked.Add(group);

            try
            {
                // Connect to group object
                using (DirectoryEntry groupObject = new DirectoryEntry("LDAP://" + group))
                {
                    // Get member of group object
                    PropertyValueCollection col = groupObject.Properties["member"] as PropertyValueCollection;

                    // Loop through each member
                    foreach (object member in col)
                    {
                        // Connect to member object
                        using (DirectoryEntry memberObject = new DirectoryEntry("LDAP://" + member))
                        {
                            // Get class of member object
                            string memberClass = memberObject.Properties["objectClass"][1].ToString();
                            string memberCN = memberObject.Properties["Name"][0].ToString();

                            if (!groupChecked.Contains(member.ToString()))
                            {
                                if (memberClass.ToLower() == "group")
                                {                                    
                                    GetMembers(member.ToString());
                                }
                                else
                                {
                                    userList.Add(memberCN);
                                }
                            }
                            else
                            {
                                if (memberClass.ToLower() != "group")
                                {
                                    userList.Add(memberCN);
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception)
            {
            }
        }
    }
}

解决方案

If you're on .NET 3.5 and up, you should check out the System.DirectoryServices.AccountManagement (S.DS.AM) namespace. Read all about it here:

Basically, you can define a domain context and easily find users and/or groups in AD:

// set up domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);

// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");

if(user != null)
{
   // get a user's group memberships 
   foreach(Principal principal in me.GetGroups())
   {
       GroupPrincipal gp = (principal as GroupPrincipal);

       if(gp != null)
       {
           // do something with the group
       }
   }
}

The new S.DS.AM makes it really easy to play around with users and groups in AD. The call to .GetGroups() also handles all the problems of nested group memberships and so forth for you - no need to deal with that hassle anymore!

这篇关于使用C#嵌套的AD用户组枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆