locked
Listing users from a specific AD group RRS feed

  • Question

  • User528996039 posted

    I want to list all the users in the group "Group CFS Handlers", and extract "sAMAccountName" etc. for each user. How can I extract this info?
    When I run my code below search.FindAll() returns 0 results. I just checked the AD and the group "Group CFS Handlers" contain one user. My code look like this:

     

    *****************************************************************
    DirectoryEntry searchRoot = new DirectoryEntry(@"LDAP://company.root");
    DirectorySearcher search = new DirectorySearcher(searchRoot);
    search.Filter = "(&(cn=Group CFS Handlers)(objectCategory=user))";
    search.PropertiesToLoad.Add("samaccountname");

    foreach (SearchResult res in search.FindAll())
    {
        string dummy = res.Properties["samaccountname"].ToString();
    }


    ****************************************************************

    I you have any idea what I do wrong, please let my know.

    Thursday, January 5, 2006 5:38 AM

All replies

  • User1354132231 posted
    The filter you are using is finding a type of 'user' and not 'group'.  This will prevent you from finding the group you wish to inspect.  Next, once you actually find the group, you should inspect the 'member' attribute of the group to see all the group's direct members.

    If you are using .NET 2.0, there is a slick way to do what you want easily (just get 'sAMAccountName').  If you are using v.1.x, then you either need to search for each returned DN and get the 'sAMAccountName', or approach from another direction and search for all users that are have "(memberOf=CN=GroupCFSblah,OU=blah,DC=blah)" filtering criteria.  Either way is about the same to do.
    Thursday, January 5, 2006 12:29 PM
  • User528996039 posted

    Hello dunnry

    Thank you very much for your reply.

    I'm using .NET 2.0. During the last 24 hours I think I have tried everything including using "samaccountname", but it will not work. I must be doing something wrong.

    Do you have some sample code that you can write for me or maybe a link to some sample code?

    Everything will help, because I'm lost:)

     

    Thursday, January 5, 2006 2:52 PM
  • User1354132231 posted
    Try this:

    DirectoryEntry group = new DirectoryEntry(
        "LDAP://CN=SomeGroup,OU=Foo,DC=domain,DC=com",
        null,
        null,
        AuthenticationTypes.Secure
        );
       
    using (group)
    {
        DirectorySearcher ds = new DirectorySearcher(
            group,
            "(objectClass=user)",
            new string[]{ "sAMAccountName" },
            SearchScope.Base
            );
           
        //we will search on 'member'
        ds.AttributeScopeQuery = "member";
       
        using (SearchResultCollection src = ds.FindAll())
        {
            foreach (SearchResult sr in src)
            {
                foreach (string key in sr.Properties.PropertyNames)
                {
                    foreach (object o in sr.Properties[key])
                    {
                        Console.WriteLine("{0}: {1}", key, o);
                    }
                }
                Console.WriteLine("=============");
            }
        }
    }


    Add or remove attributes as you desire.
    Friday, January 6, 2006 3:12 PM
  • User528996039 posted

    Hey dunnry

    Thank you very much for your sample code.
    I've tested it but ds.FindAll() creates this error:

    Unknown error (0x5011)

    Do you know this error?

    This is my code:

    DirectoryEntry group = new DirectoryEntry(LDAP://dfds.root/CN=Group CFS Handlers,OU=Common Users,DC=dfds,DC=root,null,null,AuthenticationTypes.Secure);

    using (group)
    {
               
    DirectorySearcher ds = new DirectorySearcher(group,"(objectClass=user)",new string[] { "sAMAccountName" },SearchScope.Base);

    //we will search on 'member'
    ds.AttributeScopeQuery = "member";

    using (SearchResultCollection src = ds.FindAll())
    {
                
    foreach (SearchResult sr in src)
                 {
                          
    foreach (string key in sr.Properties.PropertyNames)
                           {
                                     
    foreach (object o in sr.Properties[key])
                                      {
                                                 System.Web.
    HttpContext.Current.Response.Write(key + ": " + o);
                                       }
                            }
                  
    }
    }

    }

     

    Saturday, January 7, 2006 5:19 PM
  • User1354132231 posted
    What version of AD is your domain controllers running?  I forgot to mention that this is a Windows 2003 version only.  You will have to do it another way if you are using Windows 2000.

    Monday, January 9, 2006 1:52 PM
  • User528996039 posted
    The AD domain controller is Windows 2003 Native (on Windows 2003 platform). The web server where my code is running is Windows XP prof.
    Tuesday, January 10, 2006 4:14 AM
  • User1354132231 posted
    Interesting.  Both of those platforms support the ASQ type we are attempting to use.  Does this code work if you specifically add a username and password to the DirectoryEntry constructor in place of where the 'null' parameters are respectively?  Let's just make sure it is not a common security context issue.

    Wednesday, January 11, 2006 9:34 AM
  • User528996039 posted

    Hey dunnry

    Yes I tried to add a username and password to the DirectoryEntry, but no luck. BUT I found another way of getting my code to work. It is properply not the best solution, but it works:o)

    Here it is:

    string ldap = @LDAP://CN=GroupName,OU=Common Users,DC=company,DC=root;
    DirectoryEntry searchRoot = new DirectoryEntry(ldap);
    DirectorySearcher search = new DirectorySearcher(searchRoot);
    search.PropertiesToLoad.Add(
    "member");
    SearchResult result = search.FindOne();

    if (result != null)
    {
              
    for (int counter = 0; counter < result.Properties["member"].Count; counter++)
               {
                         
    string LDAPPath = (string)result.Properties["member"][counter];
                         
    obDirEntry = new DirectoryEntry(@"LDAP://" + LDAPPath.Replace("/", \\/));
                         PropertyCollection de = obDirEntry.Properties;
                         string
    _firstName = de["givenName"].Value.ToString();
                
    }
    }

     

    Thank you very much for your time and help.

    Thursday, January 12, 2006 5:01 AM
  • User1354132231 posted
    Well, yes that works... but a little bit by accident.  You see, you have not specified a filter, which means it defaults to "(objectClass=*)".  This is like saying 'SELECT *' in SQL.  Next, since you have bound to just the group and the default scope is Subtree it results in only 1 match.  You would not be happy with this with any other combination.  :)

    Here is the other method I was going to show you if we could not get ASQ to work (too bad, because it was made for this situation).

    DirectoryEntry group = new DirectoryEntry(
        "LDAP://CN=Group1,OU=Groups,DC=domain,DC=com",
        null,
        null,
        AuthenticationTypes.Secure
        );
       
    StringBuilder sb = new StringBuilder();

    //start an ldap filter
    sb.Append("(|");

    using (group)
    {
        foreach (string s in group.Properties["member"])
        {
            sb.AppendFormat("(distinguishedName={0})", s);
        }
    }

    //end the filter
    sb.Append(")");

    //now use the filter to find all those users
    //and just ask for what you want
    DirectoryEntry searchRoot = new DirectoryEntry(
        "LDAP://dc=domain,dc=com", //specify the root domainDNS
        null,
        null,
        AuthenticationTypes.Secure
        );
       
    using (searchRoot)
    {
        DirectorySearcher ds = new DirectorySearcher(
            searchRoot,
            sb.ToString(), //our filter we built
            new string[]{ "givenName", "sn", "sAMAccountName"}
            );
           
        using (SearchResultCollection src = ds.FindAll())
        {
            foreach (SearchResult sr in src)
            {
                foreach (string key in sr.Properties.PropertyNames)
                {
                    foreach (object o in sr.Properties[key])
                    {
                        Console.WriteLine("{0}: {1}", key, o);
                    }
                }
                Console.WriteLine("=============");
            }
        }
    }


    If you were to copy this as is and only replace the two LDAP strings (and possibly the credentials), it would do what you were looking for in a bit more of an efficient manner.  Notice I am disposing all DirectoryEntry and SearchResultCollection objects.  These objects tend to leak memory if I forget...
    Thursday, January 12, 2006 11:22 AM
  • User528996039 posted

    Hey Dunnry

    I just replaced my code with your code and it works perfect.
    Thanks.

    Jacob

    Tuesday, January 17, 2006 6:10 AM
  • User762638488 posted

    Hi,

    Can you please give me more details on how I can pull only the username in version 1.x. I have been able to get all the members of a certain group but i get all sorts of info that i don't need. all I need is tha samAccountName.

    Here's my code

    <code>

    SearchResult result;

    DirectoryEntry dsGroup = new DirectoryEntryLDAP://CN=group1,OU=Groups,DC=bla,DC=bla,DC=bla);

    DirectorySearcher search = new DirectorySearcher(dsGroup);

    search.Filter ="(&(cn=group1)(objectCategory=group))";

    search.PropertiesToLoad.Add("member");

    // search.PropertiesToLoad.Add("givenname");

    result = search.FindOne(); for (int counter = 0; counter < result.Properties["member"].Count; counter++) {

     string user = (string)result.Properties["member"][counter]; Response.Write(user);

    }

    </code>

    Thanks

    Monday, February 27, 2006 10:31 AM