4
votes

I'm trying to list all users located in an Organizational Unit within a domain using LDAP (DirectorySearcher class).

The domain I'm connecting to isn't the current domain, and the OU I'm trying to look at is in a very deep path with some of the OU names repeated elsewhere, e.g.:

MyDomain.LOCAL/MyCompany/Clients/Contoso/Financial Site/Financial Services/Users

I'm able to list all users within the domain with the following code:

// Build the directory entry
var directoryEntry = new DirectoryEntry(_ldapServer, _domain + "\\" +
    _systemUser, _systemPassword);
try
{
    // Bind to the native AdsObject to force authentication of the system user.
    // It will throw an exception if this is an invalid account
    object obj = directoryEntry.NativeObject;
}
catch (Exception ex)
{
    throw new Exception("Error authenticating system user. " + ex.Message, ex);
}

// create a directory searcher for that OU  
DirectorySearcher users = new DirectorySearcher(directoryEntry);

// set the filter to get just the users
users.Filter = "(&(objectClass=user)(objectCategory=Person))";

// add the attributes you want to grab from the search
users.PropertiesToLoad.Add("givenName");
users.PropertiesToLoad.Add("sn");
users.PropertiesToLoad.Add("mail"); 
users.PropertiesToLoad.Add("name"); 

// grab the users and do whatever you need to do with them
var allFound = users.FindAll();
foreach (SearchResult oResult in allFound)
{
    // etc
}

This works, and grabs a huge list of all the users that are located in the root (domain).
However, I wish to get the users under the specific OU.

I have tried the following line:

var directoryEntry = new DirectoryEntry(_ldapServer +
    "/ou=MyCompany/Clients/Contoso/Financial Site/Financial Services/Users",
    _domain + "\\" + _systemUser, _systemPassword);

And I get the error:

Error authenticating system user. An operations error occurred.

Does anyone know how I be more specific in the DirectorySearcher for the OU I'm interested in?


SOLVED!

The final path string (for my example) should be the following (without the line-breaks):

LDAP://DomainControllerServer/OU=Users,OU=Financial Services,
    OU=Financial Site,OU=Contoso,OU=Clients,OU=MyCompany,
    DC=MyDomain,DC=LOCAL
DomainControllerServer = IP address in my case.
-- FQDN: MyDomain.LOCAL - Period-separated into DC={part} list
 |-- OU: MyCompany
   |-- OU: Clients
     |-- OU: Contoso
       |-- OU: Financial site
         |-- OU: Financial Services
           |-- OU: Users

Remember to escape invalid characters with a backslash (\), such as any of the following: + , \ = /.

This was a nightmare, but thankfully it works now.

1
I'm using stackoverflow.com/questions/1050043/… as a starting point for browsing the OU 1 level at a time, and hopefully I'll get this working.Codesleuth

1 Answers

3
votes

The path you gave for the Users OU is not a valid LDAP path. The LDAP path is constructed in the opposite direction compared to file system path or network path as you entered. your path may look as follows: ou=Users,ou=Financial Services,ou=Financial Site,ou=Contoso,ou=Clients,dc=MyCompany

The prefixes are really important (i.e. ou= or dc=) and the path I provided may be incorrect if any of the objects is of a different class.

I recommend that inside the loop of your original code sample, print the oResult.Path and copy-paste the desired path. This way there will be no errors in constructing the LDAP path.