If you’re working within a Windows Server-based network, you
are probably using Microsoft’s Active
Directory
. Active Directory’s purpose is to reduce the number of
directories and namespaces within a network and provide a unified view of a
complex network.

You will invariably need to access the directory when
developing applications within this environment. This week, we examine a few
ways to interface with an Active Directory, and describe how you can manipulate
its data.

Active Directory primer

Before diving into .NET integration, let’s start off with a
review of Active Directory terminology.

Weekly .NET tips in your inbox

TechRepublic’s free .NET newsletter, delivered each Wednesday, contains useful tips and coding examples on topics such as Web services, ASP.NET, ADO.NET, and Visual Studio .NET.

Automatically sign up today!

Microsoft used the X.500
directory services model as a blueprint for Active Directory. The X.500
standard logically divides a directory service structure into a
servername.subdomainname.domainname.com layout. In X.500, directory information
is stored across the hierarchical layout in what is called Directory System
Agent. Microsoft designed Active Directory around many of the basic principles
of the X.500 definition, but it is not compatible with X.500 implementations.

Every object in the Active Directory has a distinguished
name, which identifies the domain where the object is located and the path by
which the object is reached. A typical distinguished name in Active Directory
is:

CN=Tony Patton,OU=Contributors,DC=TechRepublic

The components of this distinguished name include:

  • CN: The common
    name, which defines an object within the directory. In this case, the
    common name is Tony Patton.
  • OU: The organizational unit to which the object belongs.
  • DC: The domain
    of the object. It is the DNS name for the Active Directory domain, which
    is TechRepublic in our example.

As the breakdown of the distinguished name demonstrates, an
Active Directory system is arranged in a hierarchical tree. Each node on the
tree represents a resource or service available on the network. In the previous
example, the top node is TechRepublic; it contains
the Contributors OU, which can include one or more objects (it includes the
Tony Patton object). The complete path to the object is unique within the
directory tree.

Each node of the directory tree contains a set of properties
that can be retrieved and manipulated. The following terms are useful when
working with Active Directory.

  • Directory Service: An information
    source used to store information.
  • Active Directory Schema: Defines
    attributes for directory objects. It is analogous to a database schema
    that defines a database structure.

Let’s turn our attention to programmatically working with an
Active Directory.

Directory access via code

The .NET Framework provides the System.DirectoryServices namespace for Active Directory
access. It utilizes Active Directory Services Interfaces (ADSI) technology that
Microsoft provides for working with a variety of network providers. The
namespace contains two component classes:

  • DirectoryEntry: Used to work with
    individual nodes or objects in the Active Directory hierarchy. You use it
    along with helper classes to manipulate directory resources and navigate
    the directory tree. You can create, delete, rename, move a child node, and
    enumerate children.
  • DirectorySearcher: Allows you to
    perform directory queries using Lightweight Directory Access Protocol
    (LDAP), which is the only ADSI provider that supports directory searching.
    You can use the DirectoryEntry class to work with the search results.

While this isn’t an exhaustive list of the classes contained
in the namespace, it is the two most important and most-often used. The C# code in
Listing A accesses the Active Directory on my network. Listing B contains the equivalent VB.NET.

This gives you access to the Active Directory, so you can
work with directory objects. You may notice the path uses LDAP. ADSI includes
four directory service providers as listed below (I also offer the syntax for
each):

  • Windows 2000 or Windows XP: WinNT://path
  • LDAP: LDAP://path
  • Novell NetWare Directory Service: NDS://path
  • Novell NetWare 3.x: NWCOMPAT://path

Note: Working
with Active Directory does require the ADSI SDK or ADSI runtime to be installed
to create applications that utilize the functionality. It is installed by default
with Windows 2000 and XP. We can extend the sample code to access all properties of the object, as you can see in Listing C. Listing D contains the equivalent VB.NET.

With access to the directory, we may locate and manipulate
existing entries, as well as add new objects.

Changing object properties

When working with a directory, you may need to alter one or
more properties of an object. For instance, a user’s telephone number stored in
the directory may change. The code in Listing E uses the aforementioned classes to
change this property. The CommitChanges method must be
called to make the changes permanent. If you do not use this method, the
changes are not saved. The equivalent VB.NET is in Listing F.

You can use this approach with all properties. You may
encounter a situation where a new object needs to be added to the directory.

Adding a new object

It’s simple to add a new object. You begin with a
DirectoryEntry object and use the Add method of its Children property to add a
new object. It uses the hierarchical structure of the directory, so you are
adding nodes to the entry. The C# code in Listing G adds a new directory entry (a
user). Listing H contains the equivalent VB.NET.

This is a very basic example since more user information
would surely be added. You may also need to ensure the user doesn’t exist
before adding it.

Searching the directory

The DirectorySearcher class makes it easy to search for
existing objects in the directory. The C# code in Listing I conducts a search and
displays the results. The code creates an instance of the DirectorySearcher class
using the existing DirectoryEntry object. The Filter property of the
DirectorySearcher class defines the search criteria. The FindAll method returns
all objects meeting the search criteria, and a loop is used to display the path
to the matching entries. Listing J contains the equivalent VB.NET code.

Another data source

Active Directory provides a hierarchical data structure for
network data. In addition, the DirectoryEntry and DirectorySearcher classes
provide easy access to the contents of the directory via a developer’s favorite
language. You can access data in the directory as well as store new data in it.
This is another data storage area at your fingertips.

Tony Patton began his professional career as an application developer earning Java, VB, Lotus, and XML certifications to bolster his knowledge.

Miss a column?

Check out the .NET Archive, and catch up on the most recent editions of Tony Patton’s column.