C# 获取Active Directory中的用户列表

C# 获取Active Directory中的用户列表,c#,active-directory,C#,Active Directory,我正在编写一个需要从指定域获取用户列表的应用程序。我现在可以获得用户,但这是一个缓慢的方法,我如何才能更快地做到这一点,尤其是在更大的域上 using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, domain)) { UserPrincipal userPrincipal = new UserPrincipal(pc); PrincipalSear

我正在编写一个需要从指定域获取用户列表的应用程序。我现在可以获得用户,但这是一个缓慢的方法,我如何才能更快地做到这一点,尤其是在更大的域上

using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, domain))
        {
            UserPrincipal userPrincipal = new UserPrincipal(pc);

            PrincipalSearcher search = new PrincipalSearcher(userPrincipal);

            PrincipalSearchResult<Principal> results = search.FindAll();

            foreach (var principals in results.Partition(20))
            {
                IDictionary<string, string> users = new Dictionary<string, string>(20);
                foreach (UserPrincipal principal in principals.Cast<UserPrincipal>())
                {
                    users.Add(principal.SamAccountName, principal.DisplayName);
                }

                yield return users;
            }
        }
使用(PrincipalContext pc=new PrincipalContext(ContextType.Domain,Domain))
{
UserPrincipal UserPrincipal=新的UserPrincipal(pc);
PrincipalSearcher=新PrincipalSearcher(userPrincipal);
PrincipalSearchResult results=search.FindAll();
foreach(results.Partition中的var主体(20))
{
i词典用户=新词典(20);
foreach(principals.Cast()中的UserPrincipal主体)
{
添加(principal.SamAccountName,principal.DisplayName);
}
用户收益率;
}
}
基本上,在外部foreach循环中,我得到了一个IEnumerable of IEnumerable>。我这样做是为了尝试一次递增地加载一些,并在其余部分仍在加载时向用户显示它们,但一旦我点击了内部循环,我就会挂起几分钟


我也在尝试以domain\username格式获取用户名,但我也不知道该怎么做。

这相当快。我在几秒钟内得到了14k的结果。如果需要更新ui,可以使用eventhandler和其他线程

  string groupName = "Domain Users";
            string domainName = "domain";
            var results = new List<string>();
            using (var pc = new PrincipalContext(ContextType.Domain, domainName))
            {
                using (var grp = GroupPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, groupName))
                {
                    if (grp != null)
                        foreach (var p in grp.GetMembers(false))
                        {
                            results.Add(p.DisplayName);
                        }
                }
                Assert.IsTrue(results.Count > 0);
            }
string groupName=“域用户”;
字符串domainName=“domain”;
var results=新列表();
使用(var pc=new PrincipalContext(ContextType.Domain,domainName))
{
使用(var grp=GroupPrincipal.FindByIdentity(pc,IdentityType.SamAccountName,groupName))
{
如果(grp!=null)
foreach(grp.GetMembers中的var p(false))
{
结果。添加(p.DisplayName);
}
}
Assert.IsTrue(results.Count>0);
}

试试这个。它应该工作得更快

using System.DirectoryServices;

string[] RetProps = new string[] { "SamAccountName", "DisplayName" };
                //IDictionary<string, string> users = new Dictionary<string, string>();
List<string[]> users = new List<string[]>();

           foreach (SearchResult User in GetAllUsers("YourDomain", RetProps))
           {
            DirectoryEntry DE = User.GetDirectoryEntry();
            try
               {
                users.Add(new string[]{DE.Properties["SamAccountName"][0].ToString(), DE.Properties["DisplayName"][0].ToString()});
               }
               catch
               {
               }
            }


    internal static SearchResultCollection GetAllUsers(string DomainName, string[] Properties)
    {
      DirectoryEntry DE = new DirectoryEntry("LDAP://" + DomainName);
      string Filter = "(&(objectCategory=organizationalPerson)(objectClass=User))";
      DirectorySearcher DS = new DirectorySearcher(DE);
      DS.PageSize = 10000;
      DS.SizeLimit = 10000;
      DS.SearchScope = SearchScope.Subtree;
      DS.PropertiesToLoad.AddRange(Properties); DS.Filter = Filter;
      SearchResultCollection RetObjects = DS.FindAll();
      return RetObjects;
    }
  }
}
使用System.DirectoryServices;
字符串[]RetProps=新字符串[]{“SamAccountName”,“DisplayName”};
//IDictionary users=新字典();
列表用户=新列表();
foreach(GetAllUsers(“YourDomain”,RetProps)中的SearchResult用户)
{
DirectoryEntry DE=User.GetDirectoryEntry();
尝试
{
添加(新字符串[]{DE.Properties[“SamAccountName”][0].ToString(),DE.Properties[“DisplayName”][0].ToString()});
}
抓住
{
}
}
内部静态SearchResultCollection GetAllUsers(字符串域名,字符串[]属性)
{
DirectoryEntry DE=新的DirectoryEntry(“LDAP://”+域名);
字符串筛选器=“(&(objectCategory=organizationalPerson)(objectClass=User))”;
DirectorySearcher DS=新的DirectorySearcher(DE);
DS.PageSize=10000;
DS.SizeLimit=10000;
DS.SearchScope=SearchScope.Subtree;
DS.PropertiesToLoad.AddRange(属性);DS.Filter=Filter;
SearchResultCollection RetObjects=DS.FindAll();
归还物品;
}
}
}

dc是域,例如“company.com”


我不能使用它,因为我之前不知道该组或用户名。我正在尝试获取active directory中的用户列表,以便用户可以选择他们想要的用户。我想我不知道为什么您仍然不能,也许只是在组中传递。这将返回所有用户名,一旦用户选择一个,您就可以获得该用户。也就是说,我不是专家。。。我刚做了一次同样的事情,但没有成功。我不认为这是你的解决方案的一个缺陷,而是我们的广告太大了。我使用了你的方法,还将异步属性设置为true,现在加载速度更快了。谢谢。@twreid您刚刚设置了Asynchronous=true,但没有使用async或Task?
public static ArrayList GetAllActiveDirectoryUsersByDisplayName(string dc) 
            {
                ArrayList list = new ArrayList();

                PrincipalContext ctx = new PrincipalContext(ContextType.Domain, dc);
                UserPrincipal u = new UserPrincipal(ctx);

                PrincipalSearcher ps = new PrincipalSearcher(u);
                PrincipalSearchResult<Principal> results = ps.FindAll();

                foreach (UserPrincipal usr in results)
                {
                    list.Add(usr.Name);
                }

            list.Sort();

            return list; 
        }
ArrayList list = GetAllActiveDirectoryUsersByDisplayName("company.com");

                foreach (string x in list)
                {
                  Console.WriteLine(x);
                }