2009-02-04 111 views
19

我有一些代碼在一個部門中搜索所有用戶:獲取用戶列表從Active Directory在給定AD組

string Department = "Billing"; 
DirectorySearcher LdapSearcher = new DirectorySearcher(); 
LdapSearcher.PropertiesToLoad.Add("displayName"); 
LdapSearcher.PropertiesToLoad.Add("cn"); 
LdapSearcher.PropertiesToLoad.Add("department"); 
LdapSearcher.PropertiesToLoad.Add("title"); 
LdapSearcher.PropertiesToLoad.Add("memberOf"); 
LdapSearcher.Filter = string.Format("(&(objectClass=user)(department={0}))", Department); 
SearchResultCollection src = LdapSearcher.FindAll(); 

什麼將過濾器需要的樣子,如果我只是想在每個人「經理只讀「AD組?

我對這一切都錯了嗎?

回答

34

查看您的搜索我有幾個積分給你。首先,搜索使用objectClass(非索引)而不是objectCategory(索引)。該查詢存在巨大的性能問題。你最總要兩人一起取決於你試圖要檢索的結合:

(&(objectCategory=person)(objectClass=user)) = All users (no contacts) 
(&(objectCategory=person)(objectClass=contact)) = All contacts (no users) 
(&(objectCategory=person)) = All users and contacts 

對於一個羣組中的用戶可以枚舉特定組的成員對象的列表。在組對象的成員屬性中是每個用戶的distinguishedName。

This article describes enumerating members of a group...

不要忘記,你可能需要處理父組的嵌套組,因爲沒有一個默認的方式與LDAP查詢處理這個問題。爲此,您可能需要評估成員對象是否爲組,然後獲取該子組的成員屬性。

最後,你應該養成爲你的查詢指定一個dns前綴的習慣。

沒有DNS前綴:

LDAP://ou=ouname,dc=domain,dc=com 

通過域名前綴(所有三個工作):

LDAP://servername/ou=ouname,dc=domain,dc=com 
LDAP://servername.domain.com/ou=ouname,dc=domain,dc=com 
LDAP://domain.com/ou=ouname,dc=domain,dc=com 

單個域不會造成你太多問題,但是當你嘗試運行在一個搜索一個多域名的環境,你會被咬傷而沒有這個補充。希望這有助於讓你更接近你的目標。

10

我一直髮現Howto: (Almost) Everything In Active Directory via C#有助於解決大多數AD問題。

+2

這是一個非常全面的文章,但我沒有專門找到這一個。這並不意味着它不在那裏,只是我看不到它。我現在正在玩弄十幾件事... – wcm 2009-02-04 20:50:19

+0

此鏈接已損壞。我認爲這是現在應該使用的東西http://www.codeproject.com/Articles/90142/Everything-in-Active-Directory-via-C-NET-Using – Ju66ernaut 2015-09-01 20:12:36

+0

也http://www.codeproject.com/文章/ 18102/Howto-Almost-Everything-In-Active-Directory-via-C – nzpcmad 2015-09-02 19:05:05

6

如果您已經知道組的AD路徑,那麼打開DirectoryEntry可能會更容易,然後從那裏做一個DirectorySearcher。

using (DirectoryEntry de = new DirectoryEntry("LDAP://somedomain/CN=FooBar")) 
{ 
    DirectorySearcher search = new DirectorySearcher(de, ("(objectClass=user)")); 
} 

搜索器上還有一個標記,用於是否鑽取子容器,我忘記了名稱。

3

我使用下面的代碼(從http://blogs.technet.com/b/brad_rutkowski/archive/2008/04/15/c-getting-members-of-a-group-the-easy-way-with-net-3-5-discussion-groups-nested-recursive-security-groups-etc.aspx)它工作正常。

IList<string> getMembers(string domainName, string groupName) 
    { 
     PrincipalContext ctx = new PrincipalContext(ContextType.Domain, domainName); 
     GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, groupName); 

     if (grp == null) { 
      throw new ApplicationException("We did not find that group in that domain, perhaps the group resides in a different domain?"); 
     } 

     IList<string> members = new List<String>(); 

     foreach (Principal p in grp.GetMembers(true)) 
     { 
      members.Add(p.Name); //You can add more attributes, samaccountname, UPN, DN, object type, etc... 
     } 
     grp.Dispose(); 
     ctx.Dispose(); 

     return members; 
    } 
0
//Search for Group and list group members 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.DirectoryServices.AccountManagement; 

namespace ExportActiveDirectoryGroupsUsers 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      if (args == null) 
      { 
       Console.WriteLine("args is null, useage: ExportActiveDirectoryGroupsUsers OutputPath"); // Check for null array 
      } 
      else 
      { 
       Console.Write("args length is "); 
       Console.WriteLine(args.Length); // Write array length 
       for (int i = 0; i < args.Length; i++) // Loop through array 
       { 
        string argument = args[i]; 
        Console.Write("args index "); 
        Console.Write(i); // Write index 
        Console.Write(" is ["); 
        Console.Write(argument); // Write string 
        Console.WriteLine("]"); 
       } 
       try 
       { 
        using (var ServerContext = new PrincipalContext(ContextType.Domain, ServerAddress, Username, Password)) 
        { 
         /// define a "query-by-example" principal - here, we search for a GroupPrincipal 
         GroupPrincipal qbeGroup = new GroupPrincipal(ServerContext, args[0]); 

         // create your principal searcher passing in the QBE principal  
         PrincipalSearcher srch = new PrincipalSearcher(qbeGroup); 

         // find all matches 
         foreach (var found in srch.FindAll()) 
         { 
          GroupPrincipal foundGroup = found as GroupPrincipal; 

          if (foundGroup != null) 
          { 
           // iterate over members 
           foreach (Principal p in foundGroup.GetMembers()) 
           { 
            Console.WriteLine("{0}|{1}", foundGroup.Name, p.DisplayName); 
            // do whatever you need to do to those members 
           } 
          } 

         } 
        } 
        //Console.WriteLine("end"); 
       } 
       catch (Exception ex) 
       { 
        Console.WriteLine("Something wrong happened in the AD Query module: " + ex.ToString()); 
       } 
       Console.ReadLine(); 
      } 
     } 
    } 
} 
相關問題