What's the AD query syntax to enumerate all users for a particular group?

52,791

Solution 1

The third syntax works fine for me in LDP.EXE against one of my domains. I don't normally put the (objectCategory=person) in there, but it works fine with it, too.

What kind of error are you getting back when you try to use that?

Solution 2

There are several things to consider for this type of query:

  1. How many objects is this query likely to return?
  2. Do you want to expand on groups that are members of groups?
  3. Do you have to handle any "large" groups (greater 1500 members)?

You should always include "(ObjectCategory=person)" if your query will have to search a large database of users. There are several reasons you want to do this. ObjectCategory is an indexed attribute where objectClass is not, this will significantly increase your query speed on large AD databases. Also, using both the objectCategory and objectClass attributes will prevent "contact" objects from being returned in your query.

If your result set is going to return more than 1000 results, you need to be aware of performance issues. In the ADUC GUI there is a 2000 item limit that you can change via the "Options" dialogue, increasing can dramatically slow down your query. If you are going to use VBScript and enumerate over a GetObject result, this will also be VERY VERY slow, for large groups. For the Quest Powershell cmdlets you need to include the "-sizelimit" parameter to override the 1000 item limit:

get-qadgroupmember somegroup -sizelimit 0

If you are using code (VBScript, JScript, .Net) to create a connection object and add a LDAP query to it, you will need to set the ".pageSize" property on the connection object to get a paged result as the default is to not return a paged result, but to limit it to 1000 items. I usually set .pageSize to 1000 as that is the max.

Expanding nested groups is the tricky bit. The simplest way to get nested group info is to use the Quest Powershell cmdlets:

get-qadgroupmember somegroup -indirect -sizelimit 0

From a VBscript/JScript script you can use "GetObject" and enumerate over the members collection, test each member for "user or group" and then recurse into nested groups. This is slow and you shouldn't do it, except as an exercise in VBScript programming.

Ultimately you will probably want to learn to do it via a direct LDAP query. This is accomplished via the LDAP_MATCHING_RULE_IN_CHAIN operator. This operator can be difficult to use, and it can be VERY EXPENSIVE on the DC if you have a deep nesting structure for your groups. The bonus for this method is that for very large groups (over 1500 members by default) you will be able to do a query for users that are a member of the group (even indirectly), rather than retrieving the group and trying to read the member attribute (which has to be handled in a special method for "large" groups. i.e. You get a report of User objects, ratehr than a single group object where you are trying to read a large attrbiute array.

(&(objectCategory=person)(objectClass=user)(memberof:1.2.840.113556.1.4.1941:=(cn=Group1,OU=groupsOU,DC=x)))

If you are having trouble with "large" groups you can also increase the limit that AD uses when restricting access to the .member attribute.

Solution 3

Worked for days to try to produce a script that would pull from a file containing a list of user DN's and parse attributes for them. Came across your site with JFV's response and had a heart attack. Here is the script I produced from JFV's response. Basically, why read from a file when you can pull directly from the group (no error trapping yet)... This script allows me to pull the text file into Excel or other spreadsheet app and deliminate on the pipes. I can do all the sorting I want at that point. Just thought others could gain from my loss. :-(

Dim objGroup

Dim objUser

on error resume next

'Create a file and write headers
Set fs = CreateObject("Scripting.FileSystemObject")

Set f = fs.CreateTextFile ("lastpassword.txt")

f.WriteLine "firstName|initials|lastName|userPrincipalName|physicalDeliveryOfficeName|sAMAccountName|mail|cn|description|mobile|telephoneNumber|physicalDeliveryOfficeName|department|facsimileTelephoneNumber|pager"

'Search for a group name in AD and parse information to a file in pipe delimination

   Set objGroup = Getobject ("LDAP: //CN=groupname,OU=GROUPS,DC=FQDN,DC=FQDN,DC=FQDN")

   For Each objUser In objGroup.Members

      f.WriteLine objUser.firstName & "|" & _

            objUser.initials & ".|" & _

            objUser.lastName & "|" & _

            objUser.userPrincipalName & "|" & _

            objUser.physicalDeliveryOfficeName & "|" & _

            objUser.sAMAccountName & "|" & _

            objUser.mail & "|" & _

            objUser.cn & "|" & _

            objUser.description & "|" & _

            objuser.mobile & "|" & _

            objuser.telephoneNumber & "|" & _

            objuser.physicalDeliveryOfficeName & "|" & _

            objuser.department & "|" & _

            objuser.facsimileTelephoneNumber & "|" & _

            objuser.userAccountControl & "|" & _

            objUser.PasswordLastChanged

   Next

f.close

Solution 4

I thought the question is to find ALL users of A group and not find whether A user is part of A group ?

if you want to find all members of a group use

dsquery group -name "MyGroup" | dsget group -member

And if you want to find nested members also use

dsquery group -name "MyGroup" | dsget group -member -expand

If there are more than 1000 or 1500 members, dsquery might not provide results in that case use adfind.exe from joeware.net

ADFIND -f "&(objectcategory=group)(cn=MyGroup)" member 
Share:
52,791

Related videos on Youtube

ansonl
Author by

ansonl

System and Network Admin. Linguistics, learning languages and cooking as hobbies.Used to get to travel around the world and surf in and around the SF bay area, now I go camping and hiking in the Rockies. Makes music. Plays very well with others, watches cricket , eats goldfish crackers and really likes the new Doctor Who. Qui audet adipiscitur.

Updated on September 17, 2022

Comments

  • ansonl
    ansonl almost 2 years

    Here's what does not work so far;

    (&(objectCategory=Person)(objectClass=Group)(CN=group_in_question))

    (&(objectClass=Group)(objectCategory=Group)(member=CN=group_in_question))

    (&(samAccountName=%USERNAME%)(memberof=CN=group_in_question))

    (&(objectCategory=person)(objectClass=user)(memberOf=cn=group_in_question,ou=Groups,dc=mydomain,dc=com))

  • ansonl
    ansonl about 15 years
    Ahh, I should clarify a bit; I'm using the default query tool in the AD Users and Computers snap-in. Unfortunately the error condition is to simply return no value at all.. In other words, getting nothing :)
  • Spence
    Spence about 15 years
    I just created a query in AD Users and Computers for (&(objectClass=user)(memberOf=CN=Domain Admins,CN=Users,DC=ad,DC=domain,DC=com)) and found that it worked fine. Hmm... Not sure what to tell you.
  • ansonl
    ansonl about 15 years
    Hmm.. Much thanks, re-tried using your syntax but with my variables and it worked, (for displaying domain admins), then tried using path to where my group-in-question was, as well as my group-in-question and nothing, HOWEVER when I moved my group into \Users, it worked perfectly. Maybe the path to where I store that group is too deep? Something like that?
  • ansonl
    ansonl about 15 years
    Oh geezz.. Nah, it was user error. Fault was in my syntax :) I wasn't using "CN=myOUname, CN=myNextOUName", I was using, "OU=myOUName, OU=MyNextOUName", etc. Much thanks for the help and answer..
  • ansonl
    ansonl about 15 years
    GREAT answer, much thanks. Very detailed. I'm delicious'ing those two links you've got in there.
  • Ryan Fisher
    Ryan Fisher about 15 years
    This could be potentially very slow. You are probably better off moving your filter into the 'get-qadGroupMember' command with the '-ldapFilter' switch. This will cause the DC to do your filtering and return a smaller amount of items to process.
  • Joel
    Joel about 15 years
    Greg one thing I would like to caution you about using the memberOf in a LDAP query, keep in mind that you can not use wildcards with it. I know your not using a wildcard in your example, but I thought I would just make note of this.
  • Ryan Fisher
    Ryan Fisher over 14 years
    The memberOf attribute will also not return nested memberships.
  • Ryan Fisher
    Ryan Fisher over 14 years
    The objectCategory is an indexed, single-value attribute. If you have a very large directory this can help, since objectClass is NOT indexed. It will also help to exclude any computer/trust accounts you may have in the directory, which can show up in some queries as they have the 'user' class also.
  • Mike
    Mike over 11 years
    For the first two examples, instead of -member above, I had to use -members