Monday, November 09, 2009

Talking to ActiveDirectory from (Iron)Python

Active directory is one of the standard (and important) parts of a Windows network. Working with active directory is therefore a common task for a Windows system administrator. Naturally you can work with active directory from Python, but there is also good support for active directory in the .NET framework that can be accessed from IronPython (including from IronPython on Mono). This is something that Brendan McAdams has been exploring on the Evil Monkey Labs blog and has created a utility module to make it even easier:
 We're building a new intranet system at work, and I've been toying with a few things that the Windows admin asked for. Namely, since the secretaries here will update the intranet data to add people's Work & Emergency contact numbers, AIM handles, email addresses, etc. that we find a way to keep it all in sync with ActiveDirectory. Thereby keeping all the Outlooks and Blackberries up to date with the latest contact information.

This seemed like a fairly reasonable request, presuming we could figure out how to do it and since I've been using Mono and IronPython a lot more lately, I figured there would be a way to accomplish it. Most of the information I found online was either really old and/or crappy docs for doing it in C#, or more commonly using PowerShell or VBScript. So, I managed to poke around and sort out how to get IronPython on Mono (IronPython 2.6RC + Mono to find and update our users.
The end result is that I can now, from IronPython, find and update valid information on ActiveDirectory entries to reflect the latest and greatest information. One thing to note, the MS .Net ActiveDirectory APIs (System.DirectoryServices, which is mirrored in Mono) do something that confused and annoyed me. There are a limited set of 'valid' attribute keys for a user object in Active Directory (Which is really just LDAP, in case you didn't know). The DirectoryEntry object has a Properties attribute, which contains a hashmap of these values.

The object will not allow you to set an "Invalid" key (see this list for valid keys). But if you call .Properties.Keys you only get back the Properties that have values set. So, it doesn't appear to be possible to actually ask What keys are valid and do some introspective programming. I have written a wrapper class to make the DirectoryEntry properties look a bit more pythonic (but disabled support for multi-value attributes for now) - at some point in the near future i'll likely add in a "valid value" filter.

The end result is, if I want to find my own user in ActiveDirectory by my name, I can do the following from the IronPython console...

No comments:

Post a Comment

Note: only a member of this blog may post a comment.