Active Directory Utility for C#/ASP.Net

I've shown a couple of ways to interface with Active Directory but to be honest, most of them were rather basic at best. So I decided what was really needed was a basic utility class to help you, so I've come up with a couple of classes to help:

Directory.zip (2.73 kb)

This contains two files: Directory.cs and Entry.cs. Directory is the main object for connecting to your Active Directory setup, set up the search that you want to conduct, etc. It also comes with a couple of basic searches set up: get a user by user name, get all active users, and get all users. The last two can be modified further by entering your own sub filter, for example making sure they have an email address.

The second class is the entry class, which is the actual entry itself. I added some properties to help you find common things (email, phone, screen name, etc.) as well as a couple functions to help you out (Save, GetValue, and SetValue). So combined you should have enough of the functionality rolled up such that you can get started.

I will say that some functionality that I want in there is missing (entry creation/deletion, resetting/setting a user's password, etc.) and I'll add it prior to moving it over to my utility library but I think it's a decent start. Anyway, try out the code, leave feedback, and happy coding.

kick it on DotNetKicks.com   Shout it
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkListEmail

Posted by: James Craig
Posted on: 10/15/2008 at 10:24 AM
Tags: ,
Categories: C#
Post Information: Permalink | Comments (1) | Post RSSRSS comment feed

Getting All Contact Information from Active Directory

Before I go on with the code, I'd figure I'd mention this. Some of my code is now over at CodePlex... Well, not my direct code, more like a modified version. I had an email from someone who wanted to use my AES encryption code in their project (which can be found here).  As always, I said it was fine. The reason I mention this is two fold:

  1. Hopefully someone will read this, click on the link to his project and find it helpful as it does seem promising.
  2. Any bits of code I put up here are free to use. All I ask is that you link back to my site and give me some sort of credit.

Anyway, I really hope that the project works out. And definitely check it out... Now on with the code.

Many companies out there are using Active Directory. For anyone creating, or working on, a company intranet site, this can be a great boon as well as rather annoying sometimes. With ASP.Net, it's incredibly easy to set up the providers to use AD or (if you really need to) create your own providers to access it. That really isn't an issue. However, inevitably you're going to have someone ask for a bit more integration.

In my case, I had someone who wanted to do a directory search of their employees that pulled the information from AD. This is actually pretty simple to do and as always, I'm here to show you the code:

        public static List<ADEntry> GetEntry(string UserName, string Password, string SearchString)
        {
            try
            {
                List<ADEntry> ReturnValue = new List<ADEntry>();
                DirectoryEntry deDirEntry = new DirectoryEntry("LDAP://SERVERNAME",
                                                                   UserName,
                                                                   Password,
                                                                   AuthenticationTypes.Secure);
                DirectorySearcher mySearcher = new DirectorySearcher(deDirEntry);
                mySearcher.PropertiesToLoad.Add("mail");
                mySearcher.PropertiesToLoad.Add("title");
                mySearcher.PropertiesToLoad.Add("displayname");
                mySearcher.PropertiesToLoad.Add("department");
                mySearcher.PropertiesToLoad.Add("telephonenumber");

                string sFilter = String.Format("(&(objectcategory=user)(|(givenname=" + SearchString + "*)(sn=" + SearchString + "*)))");

                mySearcher.Filter = sFilter;
                mySearcher.Sort.Direction = SortDirection.Ascending;
                mySearcher.Sort.PropertyName = "cn";
                mySearcher.PageSize = 1000;

                SearchResultCollection Results;

                Results = mySearcher.FindAll();

                foreach (SearchResult Result in Results)
                {
                    ResultPropertyCollection Properties = Result.Properties;
                    ADEntry Entry=new ADEntry();
                    foreach (string Key in Properties.PropertyNames)
                    {
                        foreach (object Values in Properties[Key])
                        {
                            Entry.AddItem(Key, Values.ToString());
                        }
                    }
                    ReturnValue.Add(Entry);
                }
                return ReturnValue;
            }
            catch
            {
                return null;
            }
        }

The code above does a couple of things.  First, it connects to the AD server (which you'll have to specify).  After that, it asks the server to only return mail (email address), title (the person's title), displayname (the person's name, you could specify givenname, first name, and sn, last name, instead if you'd like), department (person's department), and telephonenumber (person's phone number/extension, depends on how it's set up). After that, it sets up the actual query. In this case the query is asking for all users who have either a last name or first name that starts with the query string. We then set the sorting and also the page size (if that isn't set we'll only get at max 1000 items returned). Finally we actually do the search and return the values.

There is one thing that I need to point out though, the code above is using a class called ADEntry. This is a simple helper class that I've created for returning information (it's similar to a StringDictionary but allows multiple entries). Anyway, it would probably be helpful if I showed that code as well, so here you go:

    /// <summary>
    /// An individual AD Entry
    /// </summary>
    public class ADEntry
    {
        #region Constructor
        /// <summary>
        /// Constructor
        /// </summary>
        public ADEntry()
        {
            _Information = new List<ADPair>();
        }
        #endregion

        #region Private Variables
        private List<ADPair> _Information=null;
        #endregion

        #region Public Properties
        /// <summary>
        /// Information for this AD Entry
        /// </summary>
        public List<ADPair> Information
        {
            get { return _Information; }
            set { _Information = value; }
        }
        #endregion

        #region Public Functions
        /// <summary>
        /// Adds an item to the entry
        /// </summary>
        /// <param name="Name">Name of the information</param>
        /// <param name="Value">Value of the entry</param>
        public void AddItem(string Name,string Value)
        {
            ADPair Item=new ADPair();
            Item.Key=Name;
            Item.Value=Value;
            Information.Add(Item);
        }
        #endregion
    }

    /// <summary>
    /// AD item pair
    /// </summary>
    public class ADPair
    {
        #region Private Variables
        private string _Key="";
        private string _Value="";
        #endregion

        #region Public Properties
        /// <summary>
        /// Key for the pair
        /// </summary>
        public string Key
        {
            get { return _Key; }
            set { _Key = value; }
        }

        /// <summary>
        /// Actual value of the pair
        /// </summary>
        public string Value
        {
            get { return _Value; }
            set { _Value = value; }
        }
        #endregion
    }

It's actually two classes, the entry and another class which is simply holds a key/value pair (the key being the items name, displayname, mail, etc., and value being the actual information).  It's basic, I know but it does the job. But that's all there is to the code. I'd probably create a business object to parse the info sent back, but other than that it's pretty much ready to go. So try out the code, leave feedback, and happy coding.

kick it on DotNetKicks.com   Shout it
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkListEmail

Posted by: James Craig
Posted on: 9/11/2008 at 2:41 PM
Tags: ,
Categories: ASP.Net | Web Design
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Getting Names and Email Addresses from Active Directory Groups

This post is short on the description side because it doesn't really need a long description. Anyway, the function listed here allows you to search active directory for the members of a given group. It's fairly straight forward and only requires two queries to AD:

        public static StringDictionary GetGroupMembers(string GroupName, string UserName, string Password)
        {
            try
            {
                StringDictionary ReturnArray = new StringDictionary();
                DirectoryEntry deDirEntry = new DirectoryEntry("LDAP://LDAPDOMAIN",
                                                                   UserName,
                                                                   Password,
                                                                   AuthenticationTypes.Secure);

                DirectorySearcher mySearcher = new DirectorySearcher(deDirEntry);
                mySearcher.PropertiesToLoad.Add("distinguishedName");

                string sFilter = String.Format("(&(objectcategory=group)(cn=" + GroupName + "))");

                mySearcher.Filter = sFilter;
                mySearcher.Sort.Direction = SortDirection.Ascending;
                mySearcher.Sort.PropertyName = "cn";

                SearchResult result;
                DirectoryEntry ResultEntry;

                result = mySearcher.FindOne();
                ResultEntry =result.GetDirectoryEntry();

                GroupName=ResultEntry.Properties["distinguishedName"].Value.ToString();

                mySearcher = new DirectorySearcher(deDirEntry);
                mySearcher.PropertiesToLoad.Add("cn");
                mySearcher.PropertiesToLoad.Add("mail");

                sFilter=String.Format("(&(memberOf={0}))", GroupName);
                mySearcher.Filter = sFilter;
                mySearcher.Sort.Direction = SortDirection.Ascending;
                mySearcher.Sort.PropertyName = "cn";
                mySearcher.PageSize = 1000;

                SearchResultCollection results;
                results = mySearcher.FindAll();

                foreach (SearchResult resEnt in results)
                {

                    ResultPropertyCollection propcoll = resEnt.Properties;
                    string Name="";
                    string Email="";
                    foreach (string key in propcoll.PropertyNames)
                    {
                        if (key == "cn")
                        {
                            foreach (object values in propcoll[key])
                            {
                                Name=values.ToString();
                            }
                        }
                        else if(key=="mail")
                        {
                            foreach (object values in propcoll[key])
                            {
                                Email=values.ToString();
                            }
                        }
                    }
                    ReturnArray.Add(Name,Email);
                }
                return ReturnArray;
            }
            catch
            {
                return null;
            }
        }

The function above does two queries. The first query finds out the distinguishedName of the group. The second query finds out who is a member of that group. All that this function requires to run is a user name, password, and the name of the group that you're looking up. You also need to go in and set the location of your LDAP server. Other than that, you're good to go. So use the code, leave feedback, and happy coding.

kick it on DotNetKicks.com   Shout it
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkListEmail

Posted by: James Craig
Posted on: 7/1/2008 at 9:38 AM
Tags:
Categories: C#
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed