【问题标题】:Enumeration of nested AD user groups using C#使用 C# 枚举嵌套的 AD 用户组
【发布时间】:2011-08-22 14:41:23
【问题描述】:

我编写了一些代码来获取组和嵌套组的所有用户。我还想确保如果组成员身份通过让第一个组成为最后一个组的成员而导致循环,则不会发生循环。

我写的代码运行正常,但是有点慢。

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

有人可以看看并告诉我代码看起来不错还是编码错误(或更糟),或者我的处理方式错误?

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

【问题讨论】:

标签: c# .net active-directory group-membership


【解决方案1】:

如果您使用的是 .NET 3.5 及更高版本,则应查看 System.DirectoryServices.AccountManagement (S.DS.AM) 命名空间。在此处阅读所有相关信息:

基本上,您可以定义域上下文并在 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
       }
   }
}

新的 S.DS.AM 让在 AD 中与用户和组一起玩变得非常容易。对.GetGroups() 的调用还可以为您处理所有嵌套组成员等问题 - 无需再处理这些麻烦!

【讨论】:

  • 我确实查看了较新的 .Net 3.5 代码,但我的最终应用程序必须在仅安装了 .net 2.0 的服务器上运行。
  • @RickBowden:但 .NET 3.5 只是 .NET 2.0 之上的一个小型“服务包”——没有什么全新的......
  • 确实如此,但我在如此严格(过度)管理的变更控制环境中工作,升级这些东西是一场噩梦。
  • @RickBowden:如果您可以向您的老板解释一下,如果您可以使用 .NET 3.5,您将在 2 小时内完成它,如果没有它,您将需要两个或三天…………
猜你喜欢
  • 1970-01-01
  • 2021-01-19
  • 2010-10-22
  • 1970-01-01
  • 1970-01-01
  • 2010-09-18
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
相关资源
最近更新 更多