Use PHP and LDAP to list members of an Active Directory group (Improved)

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

This is an improved version of the snippet posted on 2/10/2011

The Function

Example Output

Share

14 thoughts on “Use PHP and LDAP to list members of an Active Directory group (Improved)

  1. this works great, and has saved me a lot of time, thanks!
    I don’t suppose there is a way to search for multiple groups at a time?

    • Lachlan,

      I have updated the original post with a newer version of the function that allows you to specify multiple groups

      That should work for you

      • Thanks for that Sam… unfortunately, it does not work.
        when using it without specifying any groups, it works fine, but if I specify a group (exactly as provided in the example), I get the following errors:
        array_shift() expects parameter 1 to be array, null given in C:\inetpub\wwwroot\test.php on line 68
        Invalid argument supplied for foreach() in C:\inetpub\wwwroot\test.php on line 74
        the only change I made to your code when testing was I changed username/password/domain details (obviously) and changed the attributes it searches for. I even tried setting them back to as above, but to no avail.

        • The error was occurring when a ‘keep’ attribute was not found for a user (for example: a user had no telephone number value)

          I have fixed the original post, the tweaked code is:

              $i = 0; // Counter
              // Build output array
              foreach($entries as $u) {
                  foreach($keep as $x) {
                  	// Check for attribute
              		if(isset($u[$x][0])) $attrval = $u[$x][0]; else $attrval = NULL;
          
                  	// Append attribute to output array
                  	$output[$i][$x] = $attrval;
                  }
                  $i++;
              }
          
  2. Hey Sam

    Excellent code work. I build an application for a business in Denmark, where they must have 2 different logins. Admin and User login. I do not quite know how to solve this problem other than to make 2 different OU’s. but if I change:
    $ ldap_dn = “CN = ​​Users, DC = domain, DC = com”;
    to another “CN” than “Users” it comes with errors.
    hope you can help :)

      • Warning: ldap_search() [function.ldap-search]: Search: No such object in C:\wamp\www\authenticate.php on line 62

        Warning: ldap_get_entries() expects parameter 2 to be resource, boolean given in C:\wamp\www\authenticate.php on line 63

        Warning: array_shift() expects parameter 1 to be array, null given in C:\wamp\www\authenticate.php on line 66

        Warning: Invalid argument supplied for foreach() in C:\wamp\www\authenticate.php on line 72

        If I use “CN=Users” I receive the correct arrays, from the OU=Users in AD.

        • Your $ldap_dn must be incorrectly using CN instead of OU

          Right click on the object in AD Users & Computers, then go to the Object tab

          If it says ‘Object class: Container’, then use CN=XXX
          If it says ‘Object class: Organizational Unit’, then use OU=XXX

          The Users object is actually a Container and not an OU, this might be the cause of your confusion

  3. The code worked well, however I did find two issues, 1 I resolved and the other I still have not fully.

    1. The AD setup I was searching through was setup with groups in 1 OU and the users in a separate OU, both at the same level. I added a 2nd $ldap_dn variable with the OU of the Users and then passed that variable into the $results =(ldap_search($ldap,$ldap_dn2, $query);

    2. The other issue I am having is caused by users being setup with the searched group as their primary group. When you set them up this way, AD does not add the user to the member attribute of the group. I am still looking for the best solution to this issue, other than the obvious, just add them all back to the default users as their primary group. Any Ideas?

    Thanks for the great function.

    • David,

      What you need to do is add primaryGroupID=x to the LDAP query string

      To make it work, you could do this–

      Replace the foreach under ‘Append each group’ with:

      // Append each group
      foreach($group as $g) {
          if(is_numeric($g)) $query .= "(primaryGroupID=$g)"; else $query .= "(memberOf=CN=$g,$ldap_dn)";
      }
      

      And replace the line under ‘Just looking for membership of one group’ with:

      // Just looking for membership of one group
      if(is_numeric($group)) $query .= "(primaryGroupID=$group)"; else $query .= "(memberOf=CN=$group,$ldap_dn)";
      

      The code we added will detect if you are using a number instead of a string, and will then check for users that have that number as their primaryGroupID.

      The caveat being you have to use the ID of the group and not the CN, but you can mix it with CN’s since our code checks for numerics:

      print_r(get_members(513)); // Gets all users that have primaryGroupID = 513
      print_r(get_members(array("Test Group",513))); // EXCLUSIVE: Gets only members that belong to 'Test Group' AND that have primaryGroupID = 513
      print_r(get_members(array("Test Group",513),TRUE)); // INCLUSIVE: Gets members that belong to 'Test Group' OR that have primaryGroupID = 513
      

      513 is the ‘Domain Users’ group

      It’s a bit of a hack, but it should get you in the right direction

      The proper way to do it would probably be to have 2 LDAP queries run: one that looks up the group ID for each/single passed group, and the other would search against both the memberOf with the CN and the primaryGroupID with the ID

Leave a Reply

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

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>