2011-03-02 74 views
71

如何从活动目录获取用户列表?有没有办法提取用户名,名字,姓氏?我看到了类似的帖子里这样使用:如何从活动目录获取用户列表?

PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "YOURDOMAIN"); 

我从来没有做过与Active Directory,所以我完全失去了什么。任何帮助将不胜感激!

+3

阅读优秀的MSDN文章[管理目录安全主体在.NET Framework 3.5(http://msdn.microsoft.com/en-us/magazine/cc135979.aspx)为一个伟大的介绍使用AD with .NET 3.5 – 2011-03-02 05:57:38

+0

看起来像@ marc_s的文章被归档了,这是[更新的链接](http://blogs.msdn.com/b/msdnmagazine/archive/2008/01/16/7120454.aspx) – 2016-03-11 21:45:17

+0

@marc_s我很想念先生,但链接是死的。我试过这个https://blogs.msdn.microsoft.com/msdnmagazine/2008/01/16/managing-directory-security-principals-in-the-net-framework-3-5/,但即使是那篇文章的链接导致微软杂志的遗传页面 – 2017-09-07 06:25:01

回答

169

如果你是新来的Active Directory,我建议你应该先了解Active Directory如何存储数据。

Active Directory实际上是一个LDAP服务器。存储在LDAP服务器中的对象分层存储。这与将文件存储在文件系统中非常相似。这就是为什么它得名目录服务器和Active 目录

容器和Active Directory对象可通过distinguished name指定。专有名称是这样的CN=SomeName,CN=SomeDirectory,DC=yourdomain,DC=com。就像传统的关系数据库一样,您可以针对LDAP服务器运行查询。它被称为LDAP查询。

有很多方法可以在.NET中运行LDAP查询。您可以使用DirectorySearcherSystem.DirectoryServicesSearchRequestSystem.DirectoryServices.Protocol

对于您的问题,由于您要求专门查找用户主体对象,我认为最直观的方法是使用System.DirectoryServices.AccountManagement中的PrincipalSearcher。你可以很容易地从谷歌找到很多不同的例子。这是一个正在做你所要求的样品。

using (var context = new PrincipalContext(ContextType.Domain, "yourdomain.com")) 
{ 
    using (var searcher = new PrincipalSearcher(new UserPrincipal(context))) 
    { 
     foreach (var result in searcher.FindAll()) 
     { 
      DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry; 
      Console.WriteLine("First Name: " + de.Properties["givenName"].Value); 
      Console.WriteLine("Last Name : " + de.Properties["sn"].Value); 
      Console.WriteLine("SAM account name : " + de.Properties["samAccountName"].Value); 
      Console.WriteLine("User principal name: " + de.Properties["userPrincipalName"].Value); 
      Console.WriteLine(); 
     } 
    } 
} 
Console.ReadLine(); 

请注意,在AD用户对象上有许多属性。特别是,givenName会给你First Namesn会给你Last Name。关于用户名。我认为你的意思是用户登录名。请注意AD用户对象上有两个登录名称。一种是samAccountName,它也被称为Windows 2000以前的用户登录名。

UserPrincipal userPrin = new UserPrincipal(context); 
userPrin.Enabled = true; 
第一使用后

userPrincipalName如果要筛选Ÿ活跃账户将它添加到哈维的代码通常是Windows 2000中

+2

如果服务器不包含域名 – 2013-09-27 12:02:39

+0

如何使用相同的代码来列出AD组中的用户? – nJoshi 2015-07-20 22:32:41

+0

有没有一种方法使用此方法将搜索范围缩小到仅分配给电子邮件地址的目录? – ARidder101 2017-04-04 17:46:49

2

附上System.DirectoryServices.dll程序,然后使用下面的代码:

DirectoryEntry directoryEntry = new DirectoryEntry("WinNT://" + Environment.MachineName); 
string userNames="<strong class="highlight">Users</strong> : "; 
foreach (DirectoryEntry child in directoryEntry.Children) 
{ 
    if (child.SchemaClassName == "User") 
    { 
     userNames += child.Name + Environment.NewLine ;   
    } 

} 
MessageBox.Show(userNames); 
15

后使用。然后添加

searcher.QueryFilter = userPrin; 

之前找到所有。这应该让你活跃。

+0

我不认为你需要'searcher.QueryFilter = userPrin;'因为我们已经在初始化时将用户主体传递给主体搜索者,但是否则感谢提示仅对活动用户进行过滤! – Andrey 2016-09-22 18:24:20

+0

是的,Andrey是正确的所以基本上这可以被替换为在第二个使用语句中添加此属性:'使用(var searcher = new PrincipalSearcher(新UserPrincipal(context){Enabled = true}))'' – 2017-04-05 06:49:29

1

当然可以在@Harvey Kwok这里找到,但我只是想添加这个例子,因为在我的情况下我想获得一个实际的UserPrincipals列表。预先过滤此查询可能更高效,但在我的小环境中,只需稍后从列表中抽取所有内容并根据需要进行过滤即可。

根据您的需要,您可能不需要转换为DirectoryEntry,但某些属性不可用于UserPrincipal。

using (var searcher = new PrincipalSearcher(new UserPrincipal(new PrincipalContext(ContextType.Domain, Environment.UserDomainName)))) 
{ 
    List<UserPrincipal> users = searcher.FindAll().Select(u => (UserPrincipal)u).ToList(); 
    foreach(var u in users) 
     { 
      DirectoryEntry d = (DirectoryEntry)e.GetUnderlyingObject(); 
      Console.WriteLine(d.Properties["GivenName"].Value.ToString() + d.Properties["sn"].Value.ToString()); 
     } 
} 
相关问题