2012-12-07 3 views
8

Ich versuche, nach Benutzern in einer Instanz von AD LDS (ADAM) zu suchen, wo eine Eigenschaft nicht festgelegt ist, z. B. wenn die Eigenschaft "Firma" nicht auf einen Wert im ADAM-Speicher (oder AD) gesetzt ist).Wie findet man ein UserPrincipal, wo eine Eigenschaft nicht mit einem PrincipalSearcher gesetzt wird?

Wenn ich ein PrincipalSearcher und eine benutzerdefinierte UserPrincipal mit einem benutzerdefinierten AdvancedSearchFilters Objekt verwenden, erhalte ich die Fehlermeldung:

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

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

Hier Code meine Probe:

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

Antwort

8

Ändern meiner AdvanceFilters-Klasse zu den folgenden erhält die Ergebnisse, die ich brauche.

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

Es ist die "*" für den Wert an der AdvancedFilterSet.

Vielen Dank an Sean für den richtigen Weg, um die passende Antwort für die AccountManagement-Objekte zu finden.

3

Versuchen Sie, wie Sie Ihre Abfrage mit dieser :

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

Text: http://msdn.microsoft.com/en-gb/library/windows/desktop/aa746475(v=vs.85).aspx etwa auf halbem Weg die Seite sagt "Holen Sie sich alle Einträge ohne ein E-Mail-Attribut:"

+0

Ich denke, Sie sind richtig für einen Ansatz mit DirectorySearcher, aber da ich dies über die AccountManagement Objekte tun muss, ist dies nicht direkt anwendbar. – Jim

+0

+1 für mich auf die richtige Spur. – Jim

+0

Versuchen Sie dies mit den AccountManagement-Objekten PrincipalSearcher ps = new PrincipalSearcher (user); ((DirectorySearcher) ps.GetUnderlyingSearcher()). Filter = "(& (objectClass = Benutzer) (! (Firma = *)))"; / – hidden

Verwandte Themen