Как оптимизировать разложение групп AD с помощью C # .Net 3.5 - PullRequest
0 голосов
/ 20 июня 2011

Мне нужно получить членов группы для нескольких сотен групп 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; }
        }

Ответы [ 2 ]

0 голосов
/ 23 июня 2011

Я избавился от процедуры примерно на полминуты, используя фильтр 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);
        }
0 голосов
/ 20 июня 2011

Ну

Я действительно далек от того, чтобы быть экспертом, но, поскольку пользователь может принадлежать к нескольким группам ... Вы пытались запросить всех пользователей со своей группой, а затем строили группу из этого.Я предлагаю также провести профилирование, чтобы увидеть, какой метод является узким местом, и лучше понять, как действовать.

Надеюсь, это поможет.

...