Wednesday, April 29, 2009

Find users in Active Directory folder using GUID

I was recently asked to create a simple utility that fetches all users from a given organizational unit in Active Directory (This was really a part of a bigger project but that's another story). The problem was that the name of the organizational unit keeps getting changed (changed 3 times this year because of company merges and stuff like that). That means I couldn't do my normal ldap query -> LDAP:///User,OU=Software,DC=DEVTEST,DC=local because after some time the Software OU would be something else and everything would fail. Because of that I had the idea to fetch by using the object Guid which means that my program really wouldn't care if the Software OU name changed In order to accomplish that I wrote 2 small console applications to do a proof-of-concept. The first code is to fetch the GUID of all the organization unit in the Active Directory tree
DirectoryEntry entry = new DirectoryEntry("LDAP://domaincontroller", @"domain\user", "password");
entry.AuthenticationType = AuthenticationTypes.Delegation;

DirectorySearcher ds = new DirectorySearcher(entry);
//ds.Filter = "(objectClass=container)";
ds.Filter = "(objectClass=organizationalUnit)";
ds.SearchScope = SearchScope.Subtree;
ds.ServerTimeLimit = TimeSpan.FromSeconds(60);

SearchResultCollection results = ds.FindAll();

Console.WriteLine(String.Format("Found {0} results", results.Count));
foreach (SearchResult result in results)
{
   DirectoryEntry directoryEntry = result.GetDirectoryEntry();
   Console.WriteLine(String.Format("Name: {0} - GUID: {1}", directoryEntry.Name, directoryEntry.Guid));
}
Console.ReadLine();
The second code is to fetch all the users that reside in the organization unit (and sub units) with a specified GUID
DirectoryEntry entry = new DirectoryEntry("LDAP://domaincontroller/", @"domain\username", "password"); //Software organizational unit

entry.AuthenticationType = AuthenticationTypes.Delegation;

DirectorySearcher ds = new DirectorySearcher(entry);
ds.Filter = "(objectClass=user)";
ds.SearchScope = SearchScope.Subtree;
ds.ServerTimeLimit = TimeSpan.FromSeconds(60);

//Load the properties that you need
ds.PropertiesToLoad.Add("Name"); //The name of the user
ds.PropertiesToLoad.Add("SAMAccountName"); //Logon name

SearchResultCollection results = ds.FindAll();

Console.WriteLine(String.Format("Found {0} users", results.Count));
foreach (SearchResult result in results)
{
   if (result.GetDirectoryEntry().Properties["Name"].Value != null)
   {
      //Do something with the result
     Console.WriteLine(result.GetDirectoryEntry().Properties["Name"].Value.ToString() + " - " + result.GetDirectoryEntry().Path.ToString());
   }
}
Console.ReadLine();
This works and I've been changing the OU name without affecting the final results.

0 comments:

Post a Comment