6

I'm trying to run an LDAP query which will return all users which belong to the organisational units OU=Employees and OU=FormerEmployees and I am not getting anywhere.

I tried searching using the distinguishedName but that doesn't appear to support wildcards. I know there has to be an easier way but my searching effort hasn't yielded any results

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
BeepBoop
  • 184
  • 1
  • 2
  • 13
  • Do you mean **organizational unit (OU)** or **group** ?? Those are quite different and behave differently.... – marc_s Oct 11 '11 at 05:24
  • I would recommend using something like [AD Explorer](http://technet.microsoft.com/en-us/sysinternals/bb963907) to test your LDAP queries and if they work in this tool, put them in your code. – Uwe Keim Oct 11 '11 at 05:26
  • @marc_s The objectClass is OrganizationalUnit so I think that is the one I want. – BeepBoop Oct 11 '11 at 05:30
  • @UweKeim I've been playing in AD Explorer, the only way I can seem to make it work is using DistinguishedGroup endswith however when you use the ends with operator it doesn't list the query string. When I attempt in the code to say something like distinguishedgroup=*OU=Employees, etc it doesn't return anything. – BeepBoop Oct 11 '11 at 05:33

1 Answers1

13

If you're on .NET 3.5 and newer, you can use a PrincipalSearcher and a "query-by-example" principal to do your searching:

// create your domain context and define what container to search in - here OU=Employees
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "YOURDOMAIN", "OU=Employees,DC=YourCompany,DC=com");

// define a "query-by-example" principal - here, we search for a UserPrincipal 
// that is still active
UserPrincipal qbeUser = new UserPrincipal(ctx);
qbeUser.Enabled = true;

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

// find all matches
foreach(var found in srch.FindAll())
{
    // do whatever here - "found" is of type "Principal" - it could be user, group, computer.....          
}

If you haven't already - absolutely read the MSDN article Managing Directory Security Principals in the .NET Framework 3.5 which shows nicely how to make the best use of the new features in System.DirectoryServices.AccountManagement

If you prefer the "old" .NET 2.0 style, you would need to create a base DirectoryEntry that corresponds to your OU you want to enumerate objects in, and then you need to create a DirectorySearcher that searches for objects - something like this:

// create your "base" - the OU "FormerEmployees"
DirectoryEntry formerEmployeeOU = new DirectoryEntry("LDAP://OU=FormerEmployees,DC=YourCompany,DC=com");

// create a searcher to find objects inside this container
DirectorySearcher feSearcher = new DirectorySearcher(formerEmployeeOU);

// define a standard LDAP filter for what you search for - here "users"    
feSearcher.Filter = "(objectCategory=user)";

// define the properties you want to have returned by the searcher
feSearcher.PropertiesToLoad.Add("distinguishedName");
feSearcher.PropertiesToLoad.Add("sn");
feSearcher.PropertiesToLoad.Add("givenName");
feSearcher.PropertiesToLoad.Add("mail");

// search and iterate over results
foreach (SearchResult sr in feSearcher.FindAll())
{
    // for each property, you need to check where it's present in sr.Properties
    if (sr.Properties["description"] != null && sr.Properties["description"].Count > 0)
    {
       string description = sr.Properties["description"][0].ToString();
    }
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • Thanks alot. That worked a treat. I used the "old" method as that is how the existing code was written. Is there a performance advantage in using the new method, if so I may look at converting it (I'm new to LDAP routines). – BeepBoop Oct 11 '11 at 22:37
  • 1
    @user914082: I don't think the "new" S.DS.AM has any performance benefits at runtime. It's built on top of S.DS - it's *easier* to use - so your performance (writing the code) will be better - but I don't see any runtime performance benefit... – marc_s Jan 18 '12 at 10:52
  • @marc_s Can you please help me here http://stackoverflow.com/questions/40236144/need-all-users-detail-name-email-designation-department-in-the-current-orga – Akshay Oct 25 '16 at 09:31
  • @Sak: without any further information, it's impossible to help - what is the name of your **domain**?? Which **AD container** do you want to search in?? What is the problem you're having exactly - are you getting an error - if you please show it! Are you getting no data at all ? Are you getting incorrect data?? What would be the **correct** data then??? Loads of questions - without answers to these, no one will be able to help you – marc_s Oct 25 '16 at 10:50
  • From what I can tell, from people who know way more about this than me - it appears the "new" method, while potentially cleaner code, hides implementation details that can actually be much slower, at least according to https://www.gabescode.com/active-directory/2018/12/15/better-performance-activedirectory.html – neminem Jul 13 '23 at 17:12