I began working on a website which had the requirement of getting all users from Active Directory/LDAP.  I began working on a solution by searching the web. When I ran across a tool LINQ to Active Directory which allows one to use Linq against Active Directory. I found that code to be quite helpful in my task. This article discusses how to use the tool and additional code changes I created to make the tool even more specialized and less prone to memory leaks.

Steps: Get all users.

  1. Download the latest Linq to AD from codeplex LINQ to Active Directory. It expands a demo project and the main library project BdsSoft.DirectoryServices.Linq.
  2. Create a new blank solution and add the BdsSoft.DiretoryServices.Linq  project into it.
  3. Create a new project to consume the library.
  4. In the new project add these references
    1: to the BdsSoft.DirectoryServices
    2: System.DirectoryServices
    3: The com object Active DS Type library:

    Active DS Type Library in the COM tab

  5. Now we have to create our own entity. Basically it is a class where the properties are simply the name of the target LDAP categories. Here are the usings which will be needed:
    using ActiveDs;
    using BdsSoft.DirectoryServices.Linq;
    using System.Linq.Expressions;
    using System.DirectoryServices;
  6. Here is the entity class user which will hold each item:
    [DirectorySchema( "user", typeof( IADsUser ) )]
    class User
    {
        public string Name { get; set; }
    
        public string sAMAccountName { get; set; }
    
        public string objectCategory { get; set; }
    
        public string mail { get; set; }
    
        public string Description { get; set; }
    
        [DirectoryAttribute( "PasswordLastChanged", DirectoryAttributeType.ActiveDs )]
        public DateTime PasswordLastSet { get; set; }
    
        [DirectoryAttribute("distinguishedName")]
        public string Dn { get; set; }
    
        [DirectoryAttribute("memberOf")]
        public string[] Groups { get; set; }
    
    }
  7. The above class uses attributes to inform the Linq To AD library how to handle the entity and if need be change names of each of the properties of the class.
  8. Use this code to access AD from a console app, placing your AD server in the below code:
    static void Main( string[] args )
    {
    
        IEnumerable<User> users = GetADUsers();
    
        Console.WriteLine( "Users: " + users.Count().ToString() );
    
    }
    
    static DirectoryEntry ROOT = new DirectoryEntry( "LDAP://MyADDomainLocation.com" );
    
    private static IEnumerable<User> GetADUsers()
    {
        IEnumerable<User> users;
    
        var usersDS = new DirectorySource<User>( ROOT, SearchScope.Subtree );
    
                users = from usr in usersDS
                        where usr.Name == "A*" // FIlter A then any character(s)
                        select usr;
    
         users = users.OrderBy( user => user.Name ).ToList(); // Sort them alphabetically by name.
    
        return users;
    }

That will get you up and running but there are three problems with the library which you may run into.

  1. The code uses DirectorySearcher..::.FindAll Methodwhich states in the remarks that improper usage may result in a memory leak.
  2. The action even though user is stated, at least in my domain returned non users. A different LDAP category needs to be used.
  3. Doesn’t handle specific LDAP command to ignore inactive users.

I rectify those issues and will detail it in a future post.

Share