Search Active Directory for user, return user name, dept., phone # in datagrid - C#

I want to setup an asp.net page that searches active directory for a user and returns a datagrid that includes user name, department and phone number.  The search should be on the first name.  I'm using Visual Studio and C# for development.  I have the Directory connection setup fine, I just need to know how to send the value of a textbox through the search and return process.

Thanks!
JoanHerrickAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

ihenryCommented:
In .NET, you can use System.DirectoryServices API to do that.

string loginName = theTextBox.Text;

DirectoryEntry root = new DirectoryEntry();
root.Path = "LDAP://theDomain.com/dc=theDomain,dc=com";
//root.Username = "domain\user";
//root.Password = "password";

DirectorySearcher searcher  = new DirectorySearcher( root );
searcher.Filter = string.Format( "(&(objectClass=user)(objectCategory=person)(sAMAccountName={0}))", loginName );
using ( SearchResultCollection results = searcher.FindAll() )
{
      if ( results.Count > 0 )
      {
          SearchResult result = results[0];
          string firstName = "";
          if result.Properties.Contains("givenName")
          {
            firstName = result.Properties["givenName"][0];
          }
          string lastName = "";
          if result.Properties.Contains("sn")
          {
            lastName = result.Properties["sn"][0];
          }
          string department = "";
          if result.Properties.Contains("department")
          {
            department = result.Properties["department"][0];
          }
      }
      else
      {
            Console.WriteLine( "User not found." );
      }
}

Henry
0
YZlatCommented:
public DataSet GetData(string key, ref string objType, string sPath)
{
 DirectoryEntry oDir = new DirectoryEntry(sPath, usr, pwd);
 DirectorySearcher oSearcher = new DirectorySearcher(oDir);
 SearchResultCollection oSearchResultColl;
 SearchResult result;
 int iCount;
 DataSet ds = new DataSet();
 System.Data.DataTable dt;
 try {
   if (objType != "") {
     if (objType == "user") {
       if (Trim(key) != "") {
         oSearcher.Filter = ("(&(objectClass=" + objType + ")(cn=" + key + "))");
       } else {
         oSearcher.Filter = ("(objectClass=" + objType + ")");
       }
       oSearcher.PropertiesToLoad.Add("givenName");
       oSearcher.PropertiesToLoad.Add("initials");
       oSearcher.PropertiesToLoad.Add("sn");
       oSearcher.PropertiesToLoad.Add("department");
       oSearcher.PropertiesToLoad.Add("telephoneNumber");
     } else {
       oSearcher.Filter = ("(objectClass=*)");
     }
   }
   oSearchResultColl = oSearcher.FindAll();
   iCount = oSearchResultColl.Count;
   if (objType == "user") {
     dt = GetUserAttributes(oSearcher);
   } else {
   }
   if (dt.Rows.Count > 0) {
     ds.Tables.Add(dt);
   }
   return ds;
 } catch (System.Exception ex) {
   Console.Write("ERROR: " + ex.Message);
 }
}

DataTable GetUserAttributes(DirectorySearcher dSearch)
{
 try {
   System.Data.DataTable dt = new System.Data.DataTable();
   DataRow dr;
   dt.Columns.Add(new DataColumn("Last Name", typeof(string)));
   dt.Columns.Add(new DataColumn("First Name", typeof(string)));
   dt.Columns.Add(new DataColumn("Middle Init", typeof(string)));
   dt.Columns.Add(new DataColumn("Department", typeof(string)));
   dt.Columns.Add(new DataColumn("Phone", typeof(string)));
   SearchResult resultset;
   DirectoryEntry result;
   string firstName;
   string middleInit;
   string lastName;
   string dept;
   string phone;
   foreach (int resultset in dSearch.FindAll) {
     try {
       dr = dt.NewRow();
       if (!(resultset.Properties("givenName") == null)) {
         firstName = resultset.GetDirectoryEntry().Properties("givenName").Value;
       }
       if (!(resultset.Properties("initials") == null)) {
         middleInit = resultset.GetDirectoryEntry().Properties("initials").Value;
       }
       if (!(resultset.Properties("sn") == null)) {
         lastName = resultset.GetDirectoryEntry().Properties("sn").Value;
       }
       if (!(resultset.GetDirectoryEntry().Properties("telephoneNumber") == null)) {
         phone = resultset.GetDirectoryEntry().Properties("telephoneNumber").Value;
       }
       if (!(resultset.Properties("department") == null)) {
         dept = resultset.GetDirectoryEntry().Properties("department").Value;
       }
       dr("Last Name") = lastName;
       dr("First Name") = firstName;
       dr("Middle Init") = middleInit;
       dr("Department") = dept;
       dr("Phone") = phone;
       dt.Rows.Add(dr);
     } catch (System.Exception ex) {
       Console.Write("ERROR: " + ex.Message);
     }
   }
   return dt;
 } catch (System.Exception ex) {
   Console.Write("ERROR: " + ex.Message);
 }
}


After copying the two functions above, put the following in your code:

dataset ds = new dataset();
ds = GetData(TextBox1.Text, "user", "LDAP://your AD path here");
DataGrid1.DataSource = ds;
DataGrid1.BindData();
0
JoanHerrickAuthor Commented:
Not sure what I'm doing wrong - I get the same error with both suggestions which is:  System.DirectoryServices.DirectoryEntry.Properties denotes a 'property' where a 'method' was expected...
0
Cloud Class® Course: SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

JoanHerrickAuthor Commented:
Oh, I should clarify - I get this error (System.DirectoryServices.DirectoryEntry.Properties denotes a 'property' where a 'method') in reference to this line of code:

if (!(resultset.Properties("givenName") == null))
0
YZlatCommented:
if (!(resultset.GetDirectoryEntry().Properties("givenName") == null))
0
ihenryCommented:
The code in my ealier code was written by hand, sorry for the typo.

DirectoryEntry root = new DirectoryEntry();
root.Path = "LDAP://theDomain.com/dc=theDomain,dc=com";
//root.Username = "domain\user";
//root.Password = "password";

DirectorySearcher searcher  = new DirectorySearcher( root );
searcher.Filter = string.Format( "(&(objectClass=user)(objectCategory=person)(sAMAccountName={0}))", loginName );
using ( SearchResultCollection results = searcher.FindAll() )
{
      if ( results.Count > 0 )
      {
            SearchResult result = results[0];
            string firstName = "";
            if (result.Properties.Contains("givenName"))
            {
                  firstName = (string)result.Properties["givenName"][0];
            }
            string lastName = "";
            if (result.Properties.Contains("sn"))
            {
                  lastName = (string)result.Properties["sn"][0];
            }
            string department = "";
            if (result.Properties.Contains("department"))
            {
                  department = (string)result.Properties["department"][0];
            }
      }
      else
      {
            Console.WriteLine( "User not found." );
      }
}
0
JoanHerrickAuthor Commented:
lHenry - yours builds with no problem now, but how do you tie your search results to the DataGrid?
0
YZlatCommented:
put results in the DataTable and then bind the DataGrid to that table
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ihenryCommented:
string loginName = theTextBox.Text;

DirectoryEntry root = new DirectoryEntry();
root.Path = "LDAP://theDomain.com/dc=theDomain,dc=com";
//root.Username = "domain\user";
//root.Password = "password";

DirectorySearcher searcher = new DirectorySearcher( root );
searcher.Filter = string.Format( "(&(objectClass=user)(objectCategory=person)(sAMAccountName={0}))", loginName );
searcher.PropertiesToLoad.AddRange( new string[] {"givenName", "department", "telephoneNumber"} );
using ( SearchResultCollection results = searcher.FindAll() )
{
      if ( results.Count > 0 )
      {
            DataTable userTable = new DataTable( "results" );
            foreach (string colName in searcher.PropertiesToLoad)
            {
                  userTable.Columns.Add( colName, typeof(string) );
            }

            foreach (SearchResult result in results)
            {
                  DataRow dr = userTable.NewRow();
                  foreach (string colName in searcher.PropertiesToLoad)
                  {
                        if (result.Properties.Contains(colName))
                        {
                              dr[colName] = (string)result.Properties[colName][0];
                        }
                        else
                        {
                              dr[colName] = "";
                        }
                  }
            }
      }
      else
      {
            Console.WriteLine( "User not found." );
      }
}
0
JoanHerrickAuthor Commented:
Here's what ended up working for me.  I got this code from:  http://forums.asp.net/thread/1007517.aspx.  There's elements of both of your answers in this end product so I'm going to split the points.  Thanks guys.

      public DataSet FindUsers(string sFilter, string[] columns, string path, bool useCached)
            {
                  //try to retrieve from cache first
                  HttpContext context = HttpContext.Current;
                  DataSet userDS = (DataSet)context.Cache[sFilter];
           
                  if((userDS == null) || (!useCached))
                  {
                        //setup the searching entries
                        DirectoryEntry deParent = new DirectoryEntry("LDAP:  serverconnhere");
                        deParent.Username = @"username";
                        deParent.Password = "password";
                        deParent.AuthenticationType = AuthenticationTypes.Secure;
           
                        DirectorySearcher ds = new DirectorySearcher(
                              deParent,
                              sFilter,
                              columns,
                              SearchScope.Subtree
                              );

                        ds.PageSize = 1000;
           
                        using(deParent)
                        {
                              //setup the dataset that will store the results
                              userDS = new DataSet("userDS");
                              DataTable dt = userDS.Tables.Add("users");
                              DataRow dr;
       
                              //add each parameter as a column
                              foreach(string prop in columns)
                              {
                                    dt.Columns.Add(prop, typeof(string));
                              }

                              using (SearchResultCollection src = ds.FindAll())
                              {
                                    foreach(SearchResult sr in src)
                                    {
                                          dr = dt.NewRow();
                                          foreach(string prop in columns)
                                          {
                                                if(sr.Properties.Contains(prop))
                                                {
                                                      dr[prop] = sr.Properties[prop][0];
                                                }
                                          }
                                          dt.Rows.Add(dr);
                                    }
                              }
                        }
                        //cache it for later, with sliding 3 minute window
                        context.Cache.Insert(sFilter, userDS, null, DateTime.MaxValue, TimeSpan.FromSeconds(180));
                  }
                  return userDS;
            }
            
            private void Page_Load(object sender, System.EventArgs e)
            {
             
                  // Put user code to initialize the page here
            }
      


      

            private void Button1_Click(object sender, System.EventArgs e)
            {
                  string qry = String.Format("(&(objectCategory=person)(givenName={0}*))", TextBox1.Text);
                  string[] columns = new string[]{"givenName", "sn", "cn", "department", "telephoneNumber"};
                        string ldapPath = "LDAP:serverconnhere";

                  DataSet ds = FindUsers(qry, columns, ldapPath, true);
                  
             
                  {
                  DataGrid1.DataSource = ds;
                  DataGrid1.DataBind();
                  }
            }
      }
0
JoanHerrickAuthor Commented:
I agree.  I thought about it later and I'm not sure why I put that as a C.  Should be a B.  Can you change or how do I change it?
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Web Development

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.