When I needed to access Active Directory from .Net code using DirectoryServices namespace for the first time I was surprised of how much time do I have to spend to figure out how to do any simple operation.
Unlike any other .Net namespace for example System.Data (ADO.Net), System.Web and System.XML that are very good, strongly typed, object oriented and intuitive the System.DirectoryServices for some reason are not strongly typed and not intuitive at all.
So using System.DirectoryServices I always have to browse the Internet for a code samples, tips ,tricks and workarounds here is one of them.
Let’s start with the task: I had to remove a user from the “Domain Users” group membership.
Just using DEGroup.Properties["member"].Remove wouldn’t work because “Domain Users” is a “Primary Group”.
After studying the “Primary Group” concept using Microsoft material I found a lot of interesting stuff:
- MS says that you don’t need to care about primary group unless you are using Macintosh.
- But if you want to get a list of groups for a user using DirectoryServices you will get all groups except the primary group.
- If you try to get a list of users for a group you will get the list of all users except users to which this group is primary.
- Since I needed to switch the user’s primary group to remove him from this group.
Searching the internet about how to work with primary groups I found a lot of v-e-e-e-ry tricky code and most of the code is VBS,
For example: http://www.wwwcoder.com/main/parentid/260/site/2208/68/default.aspx
or
http://dunnry.com/blog/DeterminingYourPrimaryGroupInActiveDirectoryUsingNET.aspx
Here is Microsoft article:
http://support.microsoft.com/default.aspx?scid=kb;en-us;321360
But looks like this works OK for switching the primary group for a user:
if (!DEGroup.Properties.Contains("PrimaryGroupToken"))
{
DEGroup.RefreshCache(new string[]{"PrimaryGroupToken"});
}
DEUser.Properties["PrimaryGroupID"].Value = DEGroup.Properties["PrimaryGroupToken"].Value;
All this is so unintuitive that there is no way I would figure it out myself, I spent almost the whole day browsing the Internet to find these several lines of code.
Going back to comparing System.DirectoryServices and System.Data namespaces I want to say that for any task related to System.Data I never spent more that one hour and if I had to use any help just using MSDN was enough, I never had to browse Internet for tricks and workarounds just because they are not necessary.