Use PHP and LDAP to list members of an Active Directory group – version 1

Please see the UPDATED version of this script here

PHP function that gets the members of an Active Directory group, and returns the data as an array.

Input for the function: group name, user name, password

42 Comments

  1. Justin

    Forgive my ignorance, I’m pretty ignorant when it comes to PHP. Is there an easy way I can extract attributes as well as names for this? Instead of the results you would normally get, you would get something like this:

    The Manager Group contains:
    Joe Smith – 6165551212 – jsmith@globocorp.com
    Jane Doe – 6195551234 – jdoe@globocorp.com

  2. sam

    Abrahem,

    To do this you could:
    1. Query all the members of the group
    2. For each member of the group, query further details
    3. Return the array

    Tweaking the code above, you can do this:

    Ideally though, you should consider using a PHP LDAP Class for doing more advanced AD queries
    http://www.google.com/search?hl=&q=php+ldap+class

  3. Brig

    Thanks for this function. I’m having a slight problem with the function in response #5 though.

    When I run it against a group in my AD it returns an array with all the members but it’s empty. Like this:

    Array ( [0] => Array ( [0] => [1] => ) [1] => Array ( [0] => [1] => ) [2] => Array ( [0] => [1] => ) [3] => Array ( [0] => [1] => ) [4] => Array ( [0] => [1] => ) [5] => Array ( [0] => [1] => )

    I have no idea why or how to fix it.

  4. sam

    Brig, try print_r($member_list); at line 28 and verify that your first part of the function is working correctly and that the member names are returned

    See if the first array value [0] of $member_list is an array of all the members, if this output is different the following foreach loop (line 34) wont work correctly

    Afterwards, try a print_r($member_details); in that foreach loop to make sure the second ldap query is working – around line 45

    That might give you insight as to where the problem lies

  5. Brig

    Hi Sam, thanks a lot for you reply.

    I just tried your suggestions. If I put print_r($member_list); at line 28 I get the following:

    Array ( [count] => 1 [0] => Array ( [objectclass] => Array ( [count] => 2 [0] => top [1] => group ) [0] => objectclass [cn] => Array ( [count] => 1 [0] => IM-All_Users ) [1] => cn [member] => Array ( [count] => 543 [0] => CN=Jocasta Anderson,OU=Users,OU=Company,OU=London,OU=UK,DC=domain,DC=pri [1] => CN=Ian Worrad,OU=Users,OU=Company,OU=London,OU=UK,DC=domain,DC=pri [2] => CN=Beatrix Borsos,OU=Users,OU=Dusseldorf,OU=GERMANY,DC=domain,DC=pri [3] => CN=Max Ali,OU=Users,OU=Company,OU=London,OU=UK,DC=domain,DC=pri [4] => CN=Lauren Mortimer,OU=Users,OU=Company,OU=London,OU=UK,DC=domain,DC=pri [5] => CN=Michelle Brown,OU=Users,OU=Contracts Admin,OU=IT,OU=London,OU=UK,DC=domain,DC=pri [6] => CN=Louise McAleer,OU=Users,OU=Company,OU=London,OU=UK,DC=domain,DC=pri……..

    So I get all the users in thr group I’m looking for.

    When I try print_r($member_details); at line 45 I get the following:

    Array ( [count] => 0 ) Array ( [count] => 0 ) Array ( [count] => 0 ) Array ( [count] => 0 ) Array ( [count] => 0 ) Array ( [count] => 0 ) Array ( [count] => 0 ) Array ( [count] => 0 ) Array ( [count] => 0 ) Array ( [count] => 0 ) Array ( [count] => 0 ) Array ( [count] => 0 ) Array ( [count] => 0 ) Array ( [count] => 0 ) Array ( [count] => 0 ) Array ( [count] => 0 ) Array ( [count] => 0 ) Array ( [count] => 0 ) Array ( [count] => 0 ) Array ( [count] => 0 ) Array ( [count] => 0 ) Array ( [count] => 0 ) Array ( [count] => 0 )…….

    Not sure why it doesn’t pick up the details when I can return all the members.

    I really appreciate your help!

  6. Brig

    Worked it out. The problem is that our users in AD are not all located in a single OU.

    When I change

    $member_search = ldap_search($ldap, $ldap_dn, “(CN=” . $member_cn . “)”);

    on line 43 to

    $member_search = ldap_search($ldap, $base_dn, “(CN=” . $member_cn . “)”);

    Where $base_dn is the path to one of my user OU’s it starts to work.

    Just have to figure out how to query all the OU’s now. If it’s at all possible, I’m not sure yet.

    Thanks a lot for this function Sam and your help!

  7. sam

    Brig,

    Ah yes that’s right
    If the OU is different from the group’s OU then the inner ldap query needs to have a different base_dn
    Because it’s not that way for my environment, I wasn’t thinking of that situation

    To query all the members that could be in multiple OU’s, try leaving it blank (just doing the DC’s) or just putting the outer-most OU (provided that there is one)

    • sam

      Thanks Brig,

      I will also post it here

    • sam

      You just need to change the LDAP search string

      In the original example it’s:

      You would change this to something like:

      You could also provide the $ldap_dn to the OU that you want, and put in a * for your search string to return everything in that OU, like this:

      • Hans

        I tried your suggestion.
        $results = ldap_search($ldap,$ldap_dn, “ou=” . $group); not working but when I use the $results = ldap_search($ldap,$ldap_dn, “cn=*”); works and I see the outputs through print_r($member_list); But there is a problem.
        member in line 34 is an attribut of the group object. The OU dosen’t have this. So second ldap query is empty print_r($member_details); dosen’t show anything.

        • sam

          Hans,

          If you want to get everyone in a CN like ‘Users’, you can simplify things a bit:

    • sam

      Hans,

      I haven’t tested this but you should be able to put:

      Between lines 26 and 27, so it looks like:

      Where ‘cn’ is the parameter you want to sort by.

      You could also use PHP functions to sort the output array, see http://www.php.net/manual/en/array.sorting.php for options

  8. Hans

    Sam thanks for your suggestions and help. I put sort($group_member_details); between lines Line 46 and 47 and the output array was sorted.

  9. Ahmed

    The first code works for me if I put a Group name it returns the users in the group. However, I need the last code that you have that gets everyone in a OU like ‘TestUsers’. However, that last code just doesnt seem to work. It does not return anything.

    Any ideas why?

    • sam

      See if you are getting any errors:
      Make sure error_reporting and display_errors is enabled for your PHP installation
      Remove the @ in front of the ldap_bind on line 17

      Also verify that your $ldap_dn variable is correctly formed

      • Ahmed

        I am not getting any errors at all. error_reporting is enabled for my PHP installation

        I tried removing the @ in front of the ldap_bind on line 17 also no luck.

        The $ldap_dn variable is definately correctly formed because its the same one I use for your main code and that works fine. And if I change the password for the account specified, i get a message saying cannot bind. So it definately binds correctly. It Just does not output anything.

        • sam

          Ahmed,

          I have tested the code again with my AD installation

          I was able to query members of an OU (as well as an OU inside of an OU) with no issues
          Using, for example, $ldap_dn = “OU=TestUsers,DC=ad,DC=myserver”;

          Verify that your DN is the correct path to the OU you are trying to query

          How complex is your OU structure?

  10. Ahmed

    Thanks for your reply Sam. It now works great :)

    You are correct the issue was with the DN. I used the example you just gave and modified it and it worked. Thanks.

  11. Joao

    Hi sam, can you help me?

    I cannot retrieve records.

    CONFIG:

    $ldap_host = “SERVER”;
    $ldap_dn = “CN=Users,DC=sdb,DC=sucden,DC=sp”;
    $base_dn = “DC=sdb,DC=sucden,DC=sp”;
    $ldap_usr_dom = “@sdb.sucden.sp”;

    Regards.

  12. Joao

    function get_members($group,$user,$password) {
        $ldap_host = "SERVER";
        $ldap_dn = "CN=Users,DC=sdb,DC=sucden,DC=sp";
        $base_dn = "DC=sdb,DC=sucden,DC=sp";
        $ldap_usr_dom = "@sdb.sucden.sp";
        $ldap = ldap_connect($ldap_host);
     
        ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION,3);
        ldap_set_option($ldap, LDAP_OPT_REFERRALS,0);
     
        ldap_bind($ldap, $user . $ldap_usr_dom, $password);
        $results = ldap_search($ldap,$ldap_dn, "cn=" . $group);
        $member_list = ldap_get_entries($ldap, $results);
    
        $dirty = 0;
        $group_member_details = array();
     
        foreach($member_list[0]['member'] as $member) {
            if($dirty == 0) {
                $dirty = 1;
            } else {
                $member_dn = explode_dn($member);
                $member_cn = str_replace("CN=","",$member_dn[0]);
                $member_search = ldap_search($ldap, $base_dn, "(CN=" . $member_cn . ")");
                $member_details = ldap_get_entries($ldap, $member_search);
                $group_member_details[] = array($member_details[0]['givenname'][0],$member_details[0]['sn'][0],$member_details[0]['telephonenumber'][0],$member_details[0]['othertelephone'][0]);
            }
        }
        ldap_close($ldap);
        return $group_member_details;
    }
     
    // Specify the group from where to get members and a username and password with rights to query it
    $result = get_members("Users","joao","XXXXXX");
    print_r($result);
    
  13. Hi there.
    I am trying to modify your code to return the samaccountname (username) of each user, rather than their canonical name, but not having much luck!

    From what i understand, i think i will have to return the list of members as you already have, and then search LDAP again to match the canonical name to the samaccount name, but maybe there is an easier way ?

    Thanks,

    Dan.

    • sam

      You should be able to tweak the LDAP query to get a list of groups

      Try something like (objectcategory=group)(samaccountname=*)

  14. Jeffrey Meyer

    Do you know how i can pull the e-mail and username also instead of just the lastname, firstname of the users? I tried your updated code and wasn’t able to work. but this worked right away. But the real reason i need this is for all 3 values.

    • sam

      This code is only getting the attribute ‘member’ for a specific group by CN and not the individuals’ details that you are looking for.

      The ‘updated’ code takes a different approach by searching for membersOf the group, whereby you can retrieve a member’s attributes at the same time.

      Your best bet is going to be getting the updated code working.

  15. don

    that is great code. But is it possible to get the password as well from the AD ? i guess it is gonna be hashed. so do you know any possible way to manage that ?

    Thanks

  16. yoann

    It’s a very great code.

    I try to use it but i think something is missing.
    This code does not look for users whose searched group is the primary group.
    In my case some users are missing.

    However your code is very helpful. Thanks

Leave a Reply

Your email address will not be published. Required fields are marked *