Click here to Skip to main content
Licence CPOL
First Posted 5 Mar 2010
Views 4,155
Bookmarked 0 times

Setting AD Properties using the new AccountManagement API

By | 5 Mar 2010 | Technical Blog
So I'm currently programming a lightweight utility to manage LDAP objects and I came to use the new AccountManagement API introduced in .NET 3.5 because it's way easier and more object-oriented than DirectoryServices.This new namespace, as I see it, is just provided as a friendlier way to query an L
A Technical Blog article. View original blog here.[^]

So I'm currently programming a lightweight utility to manage LDAP objects and I came to use the new AccountManagement API introduced in .NET 3.5 because it's way easier and more object-oriented than DirectoryServices.

This new namespace, as I see it, is just provided as a friendlier way to query an LDAP server and is actually built on top of the plain DirectoryServices bits. And it shows... For example you have to dispose all objects performing a search (FindIdentity) or as Gary Caldwell puts it:

This call has an unmanaged memory leak because the underlying implemenation uses DirectorySearcher and SearchResultsCollection but does not call dispose on the SearchResultsCollection as the document describes.

Also, because AccountManagement is not as close to the metal as DirectoryServices you can only control whatever Microsoft chose to expose in the API.

However a fantastic feature of AccountManagement is the ability to fall back on a DirectoryServices object whenever you need to because the underlying object of any Principal is exposed through GetUnderlyingObject().

<textarea name="code" class="c#" cols="60" rows="10">


DirectoryEntry entry = (DirectoryEntry)principal.GetUnderlyingObject();
</textarea>

With that much power in our hands we can now use this to set some properties unexposed by AccountManagement. Here's a generic method I made to set LDAP properties on any Principal (users, groups, computers): <textarea name="code" class="c#" cols="60" rows="10">

public void SetCustomProperty<t>(string key, 
string value, T principal) where T : Principal
{
if (principal.GetUnderlyingObjectType() 
== typeof(DirectoryEntry))
{
DirectoryEntry entry = 
(DirectoryEntry)principal.GetUnderlyingObject();
entry.Properties[key].Value = value;
try
{
entry.CommitChanges();
}
catch (Exception e)
{
string message = String.Format(
   @"Could not set custom property {0} to value {1} for object {2}", 
   key, value, principal.Name);
throw new Exception(message, e);
}
}
}
</textarea>

Use it like this:

<textarea name="code" class="c#" cols="60" rows="10">

SetCustomProperty<userprincipal>("streetAddress", "21 jumpstreet", userPrincipal);
</textarea>

Being user-friendly while keeping control? I'm starting to like that little guy.

UPDATE: As an anonymous commenter pointed out, there's a way to actually map an AD attribute to a property of a class inheriting UserPrincipal. The technique consists of decorating the property with the attribute DirectoryProperty and the field name as parameter (as seen here).

NOTE: code indentation is messy in the examples. I need to fix something in my snippet tool.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

teebot

Software Developer
Logica
Belgium Belgium

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
-- There are no messages in this forum --
Permalink | Advertise | Privacy | Mobile
Web03 | 2.5.120517.1 | Last Updated 5 Mar 2010
Article Copyright 2010 by teebot
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid