views:

193

answers:

1

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  A: 

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.

Joshua
That's *almost* how I've got it working, +1 for sure. But there's a key step missing from the path string which I found to work last night at 1min to 5pm! The final path string I used is: `LDAP://DomainControllerServer/OU=Users,OU=Financial Services,OU=Financial Site,OU=Contoso,OU=Clients,OU=MyCompany,DC=MyDomain,DC=LOCAL`
Codesleuth
I'll tick you as answer as you're 100% right, but I'm going to edit my question to show how it should work for other people in the future. Hopefully someone else will find this question useful!
Codesleuth
Thanks for the vote :)
Joshua