Click here to Skip to main content
Click here to Skip to main content

Active Directory Searcher

, 17 Jun 2005 CPOL
Rate this:
Please Sign up or sign in to vote.
How to search Active Directory

Introduction

This tool was created to search Active Directory for user's information. But it is not complete yet. It will be very useful to get any comments on this theme.

Here is the screenshot and part of the code (see file ActiveDirectorySearcher.cs in the source code) with all the application functionality.

Sample Image - ADSScreenShot.png

using System;
using System.DirectoryServices;
using System.Windows.Forms;
using System.ComponentModel;
using System.Collections;

namespace Ads
{
    /// <span class="code-SummaryComment"><summary></span>
    /// Represents main Active Directory Searcher functionality.
    /// <span class="code-SummaryComment"></summary></span>
    [DefaultProperty("Domain")]
    public class ActiveDirectorySearcher : DirectorySearcher
    {
        private string strDomain;
        private string strAccount;
        private string strPassword;
        private AuthenticationTypes atAuthType;
        private int intNestedLevelCount;

        /// <span class="code-SummaryComment"><summary></span>
        /// Creates and initializes new class instance.
        /// <span class="code-SummaryComment"></summary></span>
        public ActiveDirectorySearcher()
        {
            base.Filter = "(objectCategory=computer)";
            intNestedLevelCount = -1;
        }

        /// <span class="code-SummaryComment"><summary></span>
        /// Gets the node in the Active Directory hierarchy where the search starts.
        /// <span class="code-SummaryComment"></summary></span>
        [Description("Path to search")]
        [Category("System")]
        [ReadOnly(true)]
        public new DirectoryEntry SearchRoot
        {
            get { return new DirectoryEntry(String.Format("LDAP://{0}", 
                  strDomain), String.Format("{0}/{1}", strDomain, strAccount), 
                  strPassword, atAuthType); }
        }

        /// <span class="code-SummaryComment"><summary></span>
        /// Sets the node in the Active Directory hierarchy where
        /// the search starts depending on the values
        /// of <span class="code-SummaryComment"><see cref="Domain"/>, etc.</span>
        /// <span class="code-SummaryComment"></summary></span>
        private void SetSearchRoot()
        {
            if((strAccount != null)&&(strAccount.Trim() != String.Empty))
                base.SearchRoot = new DirectoryEntry(String.Format("LDAP://{0}", 
                                  strDomain), String.Format("{0}/{1}", 
                                  strDomain, strAccount), strPassword, atAuthType);
            else
                base.SearchRoot = new DirectoryEntry(String.Format("LDAP://{0}", 
                                                                    strDomain));
        }

        /// <span class="code-SummaryComment"><summary></span>
        /// Domain to search name.
        /// <span class="code-SummaryComment"></summary></span>
        [Description("Domain to search")]
        [Category("Domain Definition")]
        public string Domain
        {
            get { return strDomain; }
            set
            {
                strDomain = value;
                SetSearchRoot();
            }
        }

        /// <span class="code-SummaryComment"><summary></span>
        /// Gets or sets the type of authentication to use.
        /// <span class="code-SummaryComment"></summary></span>
        [DefaultValue(AuthenticationTypes.None)]
        [Description("Authentication type")]
        [Category("Domain Definition")]
        public AuthenticationTypes AuthenticationType
        {
            get { return atAuthType; }
            set
            {
                atAuthType = value;
                SetSearchRoot();
            }
        }

        /// <span class="code-SummaryComment"><summary></span>
        /// Gets or sets the user name to use when authenticating the client.
        /// <span class="code-SummaryComment"></summary></span>
        [Description("Account in domain to login to")]
        [Category("Logging Settings")]
        public string Account
        {
            get { return strAccount; }
            set
            {
                strAccount = value;
                SetSearchRoot();
            }
        }

        /// <span class="code-SummaryComment"><summary></span>
        /// Gets or sets the password to use when authenticating the client.
        /// <span class="code-SummaryComment"></summary></span>
        [DefaultValue("")]
        [Description("Password to login to account in domain")]
        [Category("Logging Settings")]
        public string Password
        {
            get { return strPassword; }
            set
            {
                strPassword = value;
                SetSearchRoot();
            }
        }

        /// <span class="code-SummaryComment"><summary></span>
        /// Gets or sets nested levels to explore quantity.
        /// Set it to -1 to explore all available.
        /// <span class="code-SummaryComment"></summary></span>
        [DefaultValue(-1)]
        [Description("Nested levels to explore quantity. " + 
                  "Set it to -1 to explore all available.")]
        [Category("Explore Settings")]
        public int NestedLevelsToExploreQuantity
        {
            get { return intNestedLevelCount; }
            set { intNestedLevelCount = value; }
        }

        private TreeNode GetChildrenOfDirectoryEntry(DirectoryEntry cde, 
                                                       int currentLevel)
        {
            try
            {
                if((intNestedLevelCount > 0)&&(currentLevel >= intNestedLevelCount))
                  return new TreeNode("Children: max. nested level reached", 7, 8);
                TreeNode tnChilds = new TreeNode("Children", 6, 8);
                foreach(DirectoryEntry de in cde.Children)
                {
                    tnChilds.Nodes.Add(GetNodeFromDirectoryEntry(de, currentLevel+1));
                }
                return tnChilds;
            }
            catch(Exception x)
            {
                return new TreeNode("<ERROR> "+x.Message, 7, 7);
            }
        }

        private TreeNode GetDescriptionOfDirectoryEntry(DirectoryEntry de)
        {
            try
            {
                TreeNode tnDescription = new TreeNode("Description", 9, 11);
                if(de.NativeGuid != null)
                  tnDescription.Nodes.Add(new TreeNode("Native GUID: "+
                                                de.NativeGuid, 12, 14));
                else
                  tnDescription.Nodes.Add(new 
                     TreeNode("Native GUID: <NULL>", 13, 14));
                tnDescription.Nodes.Add(new TreeNode("GUID: "+ 
                                 de.Guid.ToString(), 12, 14));
                tnDescription.Nodes.Add(new TreeNode("Authentication Type: " 
                                +de.AuthenticationType.ToString(), 12, 14));
                if(de.Password != null) tnDescription.Nodes.Add(new 
                       TreeNode("Password: "+de.Password, 12, 14));
                else
                  tnDescription.Nodes.Add(new 
                      TreeNode("Password: <UNAVAILABLE>", 13, 14));
                if(de.Path != null)
                  tnDescription.Nodes.Add(new TreeNode("Path: " 
                                            +de.Path, 12, 14));
                else 
                  tnDescription.Nodes.Add(new 
                     TreeNode("Path: <NULL>", 13, 14));
                if(de.SchemaClassName != null)
                  tnDescription.Nodes.Add(new TreeNode("Schema Class Name: " 
                                              +de.SchemaClassName, 12, 14));
                else 
                  tnDescription.Nodes.Add(new 
                      TreeNode("Schema Class Name: <NULL>", 13, 14));
                if(de.Username != null)
                  tnDescription.Nodes.Add(new TreeNode("User Name: "+ 
                                               de.Username, 12, 14));
                else
                  tnDescription.Nodes.Add(new 
                           TreeNode("User Name: <NULL>", 13, 14));
                if(de.Site != null)
                  tnDescription.Nodes.Add(new TreeNode("Site: " + 
                                          de.Site.Name, 12, 14));
                else
                  tnDescription.Nodes.Add(new 
                      TreeNode("Site: <NULL>", 13, 14));
                return tnDescription;
            }
            catch(Exception x)
            {
                return new TreeNode("<ERROR> "+x.Message, 13, 13);
            }
        }

        private TreeNode GetPropertiesFromDirectoryEntry(DirectoryEntry de)
        {
            try
            {
                TreeNode tnProperties = new TreeNode("Properties", 3, 5);
                foreach(string strPropertyName in de.Properties.PropertyNames)
                {
                    TreeNode tnCurrentProperty;
                    try
                    {
                        tnCurrentProperty = new TreeNode(strPropertyName, 15, 17);
                        foreach(object objValue in de.Properties[strPropertyName])
                            tnCurrentProperty.Nodes.Add(new 
                                TreeNode(objValue.ToString(), 12, 14));
                    }
                    catch(Exception x)
                    {
                        tnCurrentProperty = new TreeNode(strPropertyName+ 
                                     ": <ERROR>: "+x.Message, 16, 16);
                    }
                    tnProperties.Nodes.Add(tnCurrentProperty);
                }
                return tnProperties;
            }
            catch(Exception x)
            {
                return new TreeNode("<ERROR> "+x.Message, 4, 4);
            }
        }

        private TreeNode GetNodeFromDirectoryEntry(DirectoryEntry de, int currentLevel)
        {
            try
            {
                string strName = (de.Name == null) ? "<UNNAMED>" : de.Name;
                RaizeSearchInfoEvent("Creating "+strName+" entry...");
                TreeNode tnResult = new TreeNode(strName, 0, 2);
                tnResult.Nodes.Add(GetDescriptionOfDirectoryEntry(de));
                tnResult.Nodes.Add(GetPropertiesFromDirectoryEntry(de));
                tnResult.Nodes.Add(GetChildrenOfDirectoryEntry(de, currentLevel));
                RaizeSearchInfoEvent(strName+" added.");
                return tnResult;
            }
            catch(Exception x)
            {
                return new TreeNode("<ERROR> "+x.Message, 1, 1);
            }
        }

        /// <span class="code-SummaryComment"><summary></span>
        /// Performs the search.
        /// <span class="code-SummaryComment"></summary></span>
        /// <span class="code-SummaryComment"><returns>Search results as tree nodes.</returns></span>
        public TreeNode[] Search()
        {
            RaizeSearchInfoEvent("Initializing...");
            ArrayList alResults = new ArrayList();
            SetSearchRoot();
            RaizeSearchInfoEvent("Starting search...");
            SearchResultCollection src = FindAll();
            RaizeSearchInfoEvent("Creating search results...");
            foreach(SearchResult sr in src)
              alResults.Add(GetNodeFromDirectoryEntry(
                            sr.GetDirectoryEntry(), 0));
            RaizeSearchInfoEvent("Search complete.");
            return (TreeNode[])(alResults.ToArray(typeof(TreeNode)));
        }

        /// <span class="code-SummaryComment"><summary></span>
        /// The search information event handler.
        /// <span class="code-SummaryComment"></summary></span>
        public delegate void SearchInfoEventHandler(string info);

        /// <span class="code-SummaryComment"><summary></span>
        /// The search information ready event.
        /// <span class="code-SummaryComment"></summary></span>
        public event SearchInfoEventHandler SearchInfo;

        /// <span class="code-SummaryComment"><summary></span>
        /// Raises the event with given information.
        /// <span class="code-SummaryComment"></summary></span>
        /// <span class="code-SummaryComment"><param name="info">Information for the event.</param></span>
        private void RaizeSearchInfoEvent(string info)
        {
            if(SearchInfo != null) SearchInfo(info);
        }
    }
}

History

  • 17th June, 2005: Initial post

License

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

Share

About the Author

Nikita D. Sinelnikoff
Web Developer
Russian Federation Russian Federation
No Biography provided

Comments and Discussions

 
GeneralI have an error Pinmemberjromagos23-Jul-07 22:20 
AnswerRe: I have an error Pinmemberh_c_a_andersen18-Aug-11 18:12 
GeneralSolution looks great need help configuring solution PinmemberchristianFeilen15-Aug-06 23:18 
QuestionHelp in implementing PinmemberchristianFeilen15-Aug-06 23:16 
GeneralArticle Text Pinmembernorm.net17-Jun-05 4:00 
GeneralRe: Article Text PinmemberMichael A. Barnhart17-Jun-05 6:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.141223.1 | Last Updated 17 Jun 2005
Article Copyright 2005 by Nikita D. Sinelnikoff
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid