For the IT Pro: coding against the Active Directory

With the .NET Directory namespaces you can do about anything with Active Directory. What about creating sites, site links, forest trusts, users? What about creating an AD self service portal in ASP.NET MVC (3)?
What about creating an app that binds to 2 domains in separate forests and then just drag the objects from the one domain to the other? Wouldn’t that be the ultimate domain migration experience?

Let’s just start by binding to that darn AD.
If you are a IT Pro you’re probably the mayor of PowerShell or Vbscript. But I’ll tell you, nothing beats the Visual Studio IDE. And C#. So go download and install it. The Express Editions are just fine.

I suppose you have a VM with Server 2008 R2 on it and did a dcpromo already, so Active Directory is in place.

In the ‘olden days’, you had to start ADSIEDIT to check out all the properties of an object. With 2008 R2 ADUC, this is no longer necessary. Look at this:

You can see all the attribute names (remove the filter if you don’t). This is important because we are going to reference these attributes in the code.

Start Visual Studio and create a new C# Console Application. Open a class file called Program.cs. This is where the program will run. When a executable is started, the code under the Main method is executed.

Now first add a reference to the namespace System.DirectoryServices dll (just right click on ‘Reference’ -> Add Reference and in the .NET tab you will find System.DirectoryServices).

This will the Program.cs:
[csharp]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;

namespace TBF.DirectoryTools.ConsoleApp
{
class Program
{

static void Main(string[] args)
{
DirectoryContext adContext = new DirectoryContext(
DirectoryContextType.Domain,
"headquarters.nl",
@"headquarters\administrator",
"MyS3cr3t");

Domain domain = Domain.GetDomain(adContext);
DirectoryEntry entry = new DirectoryEntry(
"LDAP://headquarters.nl/OU=Accounts,DC=headquarters,DC=nl");

DirectorySearcher searcher = new DirectorySearcher(
entry, "(&(objectClass=user)(objectCategory=Person))");
searcher.PropertiesToLoad.Add("givenName");

SearchResultCollection src = searcher.FindAll();

foreach (SearchResult res in src)
{
DirectoryEntry user = new DirectoryEntry(res.Path);
user.Properties["description"].Add("Temp account");
user.Properties["displayName"].Add("Whatever");
user.CommitChanges();
}

Console.ReadKey();

}
}
}

[/csharp]

Explanation:

First, we must add the namespace of the dll to Program.cs:

[csharp]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
[/csharp]

The Main method is the method that gets executed.
Let’s start with logging in. We’ll create an instance of the DirectoryContext class. The parameters are the domainname, the username and the password:

[csharp]
static void Main(string[] args)
{
DirectoryContext adContext = new DirectoryContext(
DirectoryContextType.Domain,
"headquarters.nl",
@"headquarters\administrator",
"MyS3cr3t");
[/csharp]

So the password is hardcoded but that’s something we need to take care of later. First let’s just get proof of concept of binding the AD. My laptop does not have to be a member of the domain, but I have to make sure I can resolve the domain name. So check your DNS settings if it doesn’t work.

Now that we are connected to the domain, let’s specify the path to the OU I would like to code against (the users are all in the OU Accounts):

[csharp]
Domain domain = Domain.GetDomain(adContext);
DirectoryEntry entry = new DirectoryEntry(
"LDAP://headquarters.nl/OU=Accounts,DC=headquarters,DC=nl");
[/csharp]

Now, let’s create a filter. Or a ‘WHERE’ clause if you wish.

[csharp]
DirectorySearcher searcher = new DirectorySearcher(
entry, "(&(objectClass=user)(objectCategory=Person))");
SearchResultCollection src = searcher.FindAll();
[/csharp]

SearchResultCollection implements IEnumerable, so we can iterate the results with a foreach loop and add the desired attributes:

[csharp]
foreach (SearchResult res in src)
{
DirectoryEntry user = new DirectoryEntry(res.Path);
user.Properties["description"].Add("Temp account");
user.Properties["displayName].Add("Whatever");
user.CommitChanges();
}

[/csharp]

Now if you run this code, you will see that every user account in the Accounts OU has now a description of “Temp account” and a displayname of “Whatever”.

This was a bit boring, wasn’t it?

But the fun thing is, we now know how we can fetch data from a database and push it in Active Directory, just by following this principle. We could also create a web form and let users fill in their details themselves.

Next time, I will explore Linq to AD. That’s right. Querying AD with Linq and using Lambda’s!

One Reply to “For the IT Pro: coding against the Active Directory”

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: