2012-12-07 8 views
8

Próbuję wyszukać użytkowników w wystąpieniu AD LDS (ADAM), w którym nie jest ustawiona właściwość, na przykład gdy właściwość "firma" nie jest ustawiona na wartość w sklepie ADAM (lub AD w tym przypadku).Jak znaleźć element UserPrincipal, w którym właściwość nie jest ustawiona przy użyciu polecenia PrincipalSearcher?

Kiedy używam PrincipalSearcher i zwyczaj UserPrincipal z niestandardowych AdvancedSearchFilters obiektu, pojawia się błąd:

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

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

Oto mój przykładowy kod:

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); 
     } 
    } 
} 

Odpowiedz

8

Modyfikowanie mojej klasy AdvanceFilters do poniższych zapewnia wyniki, których potrzebuję.

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); 
    } 
} 

To "*" za część wartości w AdvancedFilterSet.

Dziękuję Seanowi za doprowadzenie do właściwego szlaku, aby uzyskać odpowiedź odpowiednią dla obiektów AccountManagement.

3

Spróbuj użyć tego jako zapytaniu :

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

Dokumenty: http://msdn.microsoft.com/en-gb/library/windows/desktop/aa746475(v=vs.85).aspx mniej więcej w połowie strony pojawia się komunikat "Pobierz wszystkie wpisy bez atrybutu wiadomości e-mail:"

+0

Myślę, że masz rację, jeśli chodzi o podejście z użyciem usługi DirectorySearcher, ale ponieważ muszę to zrobić za pośrednictwem obiektów AccountManagement, nie ma to bezpośredniego zastosowania. – Jim

+0

+1 za umieszczenie mnie na właściwym szlaku. – Jim

+0

Spróbuj tego za pomocą obiektów AccountManagement PrincipalSearcher ps = new PrincipalSearcher (użytkownik); ((DirectorySearcher) ps.GetUnderlyingSearcher()). Filter = "(& (objectClass = user) (! (Company = *)))"; / – hidden

Powiązane problemy