Thursday, January 03, 2008

.NET 3.5 (finally) brings some decent Active Directory support!

Back in the old days (like AD Change Password WebPart and Account locked WebPart) you had to use the "Active DS Type Library" (Interop.ActiveDs.dll) to interact with Active Directory to retrieve things like :

  • Change Password
  • Lockout Time
  • Last password change date
  • Change users password, etc

Now there is .NET 3.5 with the inclusion of System.DirectoryServices.AccountManagement! Using this piece, gone are the days when you had to invoke a property and you got a LargeInteger as a return value which you had to split up in a high and a low part and make a datetime thing out of it (see samples below to see what i'm talking about ;))


bool isDisabled; isDisabled = ((int)entry.Properties["userAccountControl"].Value & (int)ADS_USER_FLAG.ADS_UF_ACCOUNTDISABLE) != 0;

object lastlogon = entry.InvokeGet("LastLogin");

LargeInteger liAcctPwdChange = entry.Properties["pwdLastSet"].Value as LargeInteger; // Convert the highorder/loworder parts of the property pulled to a long. long dateAcctPwdChange = (((long)(liAcctPwdChange.HighPart) << 32) + (long)liAcctPwdChange.LowPart); DateTime dtAcctPwdChange = DateTime.FromFileTime(dateAcctPwdChange);

Nowadays your code will look like this

PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "domain", "DC=domain,DC=com"); // Create an in-memory user object to use as the query example. UserPrincipal u = new UserPrincipal(ctx); // Set properties on the user principal object. u.SamAccountName = "Robin"; // Create a PrincipalSearcher object to perform the search. PrincipalSearcher ps = new PrincipalSearcher(); ps.QueryFilter = u; PrincipalSearchResult<Principal> results = ps.FindAll(); foreach (UserPrincipal _user in results) { DateTime LastPasswordChange = _user.LastPasswordSet; DateTime LockoutTime = _user.AccountLockoutTime; DateTime ExpirationDate = _user.AccountExpirationDate; int FailedLogonAttempts = _user.BadLogonCount; bool UserDisabled = _user.Enabled; bool UserLockedOut = _user.IsAccountLockedOut; }

Pretty sweet eh? No more Googling to find out which property in AD you need to address in order to get things working :)


biozal said...

Hey I wrote up a quick blog entry on how to make a custom User object to get access to fields that aren't in the basic UserPrincipal object.

Costoda's Blog

paul.s.davis said...

Hi Robin, thanks for the messenger chat last night... I found an example (finally) for using an extended userprincipal object :)

Brian Miller said...

Thanks for psoting this.

Brian Miller

bmack500 said...

I assume you still need to use RootDSE to fetch the forest & domain and such? It looks like you've hard coded the domain.

sharepoint said...

heyy buddy thnx for posting was of great help.... the sharepoint data is really helpful thankss keep it up !

Fewlines4Biju said...

Valuabel Information !!! Thanks a Lot for Sharing !!! Keep It Up!!!


SharePoint 2010 Blogs -
MOSS 2007-
Personal Blogs -
Interview Questions -
Asp.Net -

Katpro said...

thanks for the post
its really seful information
thank you

digital signature Microsoft said...

A friend of mine pointed out your blog to me last summer and I have been following you ever since. I love all your diy posts. They are always full of innovative ideas and your tutorials are terrific!!