2012-12-07 12 views
8

Tôi đang cố gắng tìm người dùng trong trường hợp AD LDS (ADAM) trong đó thuộc tính không được đặt, ví dụ: thuộc tính "công ty" không được đặt thành giá trị trong cửa hàng ADAM (hoặc AD cho vấn đề đó)).Cách tìm UserPrincipal ở đâu một thuộc tính không được thiết lập bằng cách sử dụng một PrincipalSearcher?

Khi tôi sử dụng một PrincipalSearcher và một tùy chỉnh UserPrincipal với một đối tượng tùy chỉnh AdvancedSearchFilters, tôi nhận được lỗi:

An unhandled exception of type 'System.ArgumentException' occurred in System.DirectoryServices.dll 

Additional information: The (&(objectClass=user)(!(company=))) search filter is invalid. 

Dưới đây là mẫu mã của tôi:

using System; 
using System.DirectoryServices.AccountManagement; 
using System.Security.Permissions; 
using System.Linq; 

namespace AdamDump 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      PrincipalContext context = new PrincipalContext(ContextType.ApplicationDirectory, "MyAdamInstance:50000", "OU=Adam Users,dc=apps01,dc=mydomain", "queryaccount", "password");   

      // initialize a Query By Example 
      using (MyUserPrincipal myUserPrincipal = new MyUserPrincipal(context)) 
      { 
       myUserPrincipal.MyAdvancedFilters.WhereCompanyNotSet(); 

       PrincipalSearchResult<Principal> principals = null; 

       // do the search... 
       using (PrincipalSearcher principalSearcher = new PrincipalSearcher(myUserPrincipal)) 
       { 
        principals = principalSearcher.FindAll(); 
       } 

       var myUsers = principals.Select(principal => principal as MyUserPrincipal).ToList(); 

       foreach (var user in myUsers) 
        Console.WriteLine("Name: {0}, Account{1}", user.DisplayName, user.SamAccountName); 

       Console.WriteLine("Total found: {0}", myUsers.Count); 
      }     
     } 
    } 


    [DirectoryObjectClass("user")] 
    [DirectoryRdnPrefix("CN")] 
    [EnvironmentPermissionAttribute(SecurityAction.LinkDemand, Unrestricted = true)] 
    public class MyUserPrincipal : UserPrincipal 
    { 
     private MyAdvancedFilters _myAdvancedFilters; 

     /// <summary> 
     /// Initializes a new instance of the <see cref="MyUserPrincipal"/> class. 
     /// </summary> 
     /// <param name="context">A <see cref="PrincipalContext"/> to associate this instance with.</param> 
     [EnvironmentPermissionAttribute(SecurityAction.LinkDemand, Unrestricted=true)] 
     public MyUserPrincipal(PrincipalContext context) 
      : base(context) { } 

     public MyAdvancedFilters MyAdvancedFilters 
     { 
      get 
      { 
       return this.AdvancedSearchFilter as MyAdvancedFilters; 
      } 
     } 

     public override AdvancedFilters AdvancedSearchFilter 
     { 
      get 
      { 
       if (_myAdvancedFilters == null) 
       { 
        _myAdvancedFilters = new MyAdvancedFilters(this);      
       } 

       return _myAdvancedFilters; 
      } 
     } 
    } 

    public class MyAdvancedFilters : AdvancedFilters 
    { 
     /// <summary> 
     /// Initializes a new instance of the <see cref="MyAdvancedFilters"/> class. 
     /// </summary> 
     /// <param name="principal">The source <see cref="Principal"/></param> 
     public MyAdvancedFilters(Principal principal) : base(principal) { } 

     public void WhereCompanyNotSet() 
     { 
      this.AdvancedFilterSet("company", "", typeof(string), MatchType.NotEquals); 
     } 
    } 
} 

Trả lời

8

Sửa đổi lớp AdvanceFilters của tôi sau đây sẽ nhận được kết quả tôi cần.

public class MyAdvancedFilters : AdvancedFilters 
{ 
    /// <summary> 
    /// Initializes a new instance of the <see cref="MyAdvancedFilters"/> class. 
    /// </summary> 
    /// <param name="principal">The source <see cref="Principal"/></param> 
    public MyAdvancedFilters(Principal principal) : base(principal) { } 

    public void WhereCompanyNotSet() 
    { 
     this.AdvancedFilterSet("company", "*", typeof(string), MatchType.NotEquals); 
    } 
} 

Đây là "*" cho phần giá trị trong AdvancedFilterSet.

Nhờ Sean đã dẫn đến đường mòn phù hợp để tìm ra câu trả lời phù hợp cho các đối tượng AccountManagement.

3

Hãy thử sử dụng điều này như truy vấn của bạn :

(&(objectClass=user)(!(company=*))) 

Tài liệu: http://msdn.microsoft.com/en-gb/library/windows/desktop/aa746475(v=vs.85).aspx khoảng một nửa xuống trang có nội dung "Nhận tất cả các mục nhập không có thuộc tính email:"

+0

Tôi nghĩ bạn thích hợp với cách tiếp cận bằng cách sử dụng DirectorySearcher nhưng vì tôi cần thực hiện điều này thông qua các đối tượng AccountManagement, điều này không thể áp dụng trực tiếp. – Jim

+0

+1 để đặt tôi vào đường mòn bên phải. – Jim

+0

Hãy thử điều này với các đối tượng AccountManagement PrincipalSearcher ps = new PrincipalSearcher (người dùng); ((DirectorySearcher) ps.GetUnderlyingSearcher()). Filter = "(& (objectClass = user) (! (Company = *)))"; / – hidden

Các vấn đề liên quan