0

我需要检索数百个 AD 组的组成员。虽然下面的代码给出了正确的答案,但它非常慢。是否有更有效的方法将这些组分解为其成员?

我目前的方法是使用System.DirectoryServices.AccountManagement. 我有一List<T>组要搜索的组名。遍历每个并调用GroupPrincipal.GetMembers()每个(目前此代码需要 2 分钟以上才能分解大约 100 个组;我的目标将在 15 秒以下)

[EnvironmentPermissionAttribute(SecurityAction.LinkDemand, Unrestricted = true)]
        private static void GetGroupMembership(List<ActiveDirectoryPrincipalProperties> userGroupProperties)
        {
            List<ActiveDirectoryPrincipalProperties> groupProperties = new List<ActiveDirectoryPrincipalProperties>();

            foreach (ActiveDirectoryPrincipalProperties gProperties in userGroupProperties)
            {
                if (gProperties.groupYesNo)
                {
                    PrincipalContext ctx = new PrincipalContext(ContextType.Domain, gProperties.groupDomain);
                    try
                    {
                        GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, gProperties.groupName);

                        foreach (Principal member in group.GetMembers(true))
                        {
                            ActiveDirectoryPrincipalProperties memberProperties = new ActiveDirectoryPrincipalProperties();
                            memberProperties.fullGroupName = gProperties.fullGroupName;
                            memberProperties.groupDomain = gProperties.groupDomain;
                            memberProperties.groupName = gProperties.groupName;
                            memberProperties.groupType = gProperties.groupType;
                            memberProperties.groupYesNo = false;
                            memberProperties.memberDomain = member.Context.Name.ToString();
                            memberProperties.memberName = member.SamAccountName.ToString();
                            memberProperties.memberType = member.StructuralObjectClass.ToString();
                            memberProperties.sqlUserOnlyYesNo = false;

                            groupProperties.Add(memberProperties);
                        }
                        group.Dispose();
                    }
                    finally
                    {
                        ctx.Dispose();
                    }
                }

            }

            userGroupProperties.AddRange(groupProperties);
        }

        public class ActiveDirectoryPrincipalProperties
        {
            public string fullGroupName { get; set; }
            public string groupDomain { get; set; }
            public string groupName { get; set; }
            public string groupType { get; set; }
            public string memberDomain { get; set; }
            public string memberName { get; set; }
            public string memberType { get; set; }
            public bool groupYesNo { get; set; }
            public bool sqlUserOnlyYesNo { get; set; }
        }
4

2 回答 2

0

我真的远不是专家,但是,因为一个用户可以属于多个组......您是否尝试过请求他的组的所有用户,然后从中构建组。我还建议进行一些分析,看看哪种方法是瓶颈,并更好地了解如何进行。

希望能帮助到你。

于 2011-06-20T14:34:47.587 回答
0

在迭代它的元素并删除方法中的一个条件语句之前,我使用列表中的 LAMDA 过滤器从我的过程中缩短了大约半分钟。这是我更新的代码。

[SecurityCritical]
        [SecurityPermissionAttribute(SecurityAction.Demand)] 
        private static void GetGroupMembership(List<ActiveDirectoryPrincipalProperties> userGroupProperties)
        {
            List<ActiveDirectoryPrincipalProperties> groupProperties = new List<ActiveDirectoryPrincipalProperties>();

            foreach (ActiveDirectoryPrincipalProperties gProperties in userGroupProperties.FindAll(token => token.groupYesNo.Equals(true)))
            {

                PrincipalContext ctx = new PrincipalContext(ContextType.Domain, gProperties.groupDomain);
                try
                {

                    GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, gProperties.groupName);

                    foreach (Principal member in group.GetMembers(true))
                    {
                        ActiveDirectoryPrincipalProperties memberProperties = new ActiveDirectoryPrincipalProperties();
                        memberProperties.fullGroupName = gProperties.fullGroupName;
                        memberProperties.groupDomain = gProperties.groupDomain;
                        memberProperties.groupName = gProperties.groupName;
                        memberProperties.groupType = gProperties.groupType;
                        memberProperties.groupYesNo = false;
                        memberProperties.memberDomain = member.Context.Name.ToString();
                        memberProperties.memberName = member.SamAccountName.ToString();
                        memberProperties.memberType = member.StructuralObjectClass.ToString();
                        memberProperties.sqlUserOnlyYesNo = false;

                        groupProperties.Add(memberProperties);
                    }
                    group.Dispose();
                }
                finally
                {
                    ctx.Dispose();
                }


            }

            userGroupProperties.AddRange(groupProperties);
        }
于 2011-06-23T14:21:42.210 回答