How Can I Count the Number of Users in a Group?

How Can I Count the Number of Users in a Group?

  • Comments 5
  • Likes
Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I count the number of users in an Active Directory group?

-- TP

SpacerHey, Scripting Guy! AnswerScript Center

Hey, TP. You know, it’s our sad duty to confirm that the reports currently sweeping the Internet are true. Without wishing to alarm anyone, we must admit that one of the Around the World With Dr. Scripto Bobblehead pictures appears to be a fake! (And no, we’re not talking about the obvious one at the end.)

Please, please; there’s no need to panic. The Scripting Guys are working closely with representatives of the World Health Organization and we are confident that this fake picture poses no health hazard of any kind. (Although doctors do recommend that pregnant women and those with weak hearts stay away from the Script Center until the this issue has been resolved.) In addition, you can rest assured that the safety and well-being of Script Center users remains our highest priority: if the situation begins to get even slightly out of control we will shut down the Script Center and quarantine the Scripting Guys immediately.

Which, come to think of it, is the very thing our manager recommends each time we meet with him.

We should hasten to add that, at this point in time, we do not know for sure that one of the pictures is a fake; we currently have a team of forensic scientists and art experts examining all the evidence. Obviously this is a very serious matter, and we do not want to make any hasty accusations. Because of that, our investigation will take some time to complete. But trust us: we will get to the bottom of this.

And what will we do if we discover that one of the pictures is a fake? To be honest, we haven’t reached a consensus on that; however, Scripting Guy Jean Ross is currently standing by with a team of highly-trained commandos, ready to parachute into action on a moment’s notice. But, then again, Scripting Guy Jean Ross is always ready to parachute into action at a moment’s notice:

“Someone has a question about text files? My team and I will parachute in.”

“There’s a missing period in one of the Sesame Script articles? My team and I will parachute in.”

“Someone brought doughnuts and left them in the kitchen? My team and I will parachute in.”

Note. Shouldn’t someone talk to her about this erratic behavior? You bet they should. On the other hand, she’s continually surrounded by a team of highly-trained commandos. You go tell her she’s acting crazy!

Needless to say, we will keep you informed as more information becomes available. In the meantime, we would like to show you a script that can count the number of users in an Active Directory group. And don’t worry: this script comes with the Scripting Guys Certificate of Authenticity, ensuring that it is a real Scripting Guys script and not a fake.

If it doesn’t say Scripting Guys on it, you don’t know what’s inside.

Here’s the script:

Set objGroup = GetObject("LDAP://CN=Finance Employees,OU=Finance,DC=fabrikam,DC=com")

i = 0

Set objDictionary = CreateObject("Scripting.Dictionary")

For Each strUser in objGroup.Member
    i = i + 1

    Set objMember = GetObject("LDAP://" & strUser)
    strType = objMember.Class

    If Not objDictionary.Exists(strType) Then
        objDictionary.Add strType, "1"
    Else
        objDictionary.Item(strType) = objDictionary.Item(strType) + 1
    End If
Next

Wscript.Echo "Total members in the group: " & i
Wscript.Echo

For Each objType in objDictionary
    Wscript.Echo objType & ": " & objDictionary.Item(objType)
Next

Two things we should note before we go much further. First, the only way to determine the number of members in a group is to go ahead and count those members; ADSI doesn’t have a Count property that can instantly return the number of items in a collection for us. (Or at least it doesn’t have a Count property that actually works.)

Second, we could have written a simpler version of this script, one that looks like this:

Set objGroup = GetObject("LDAP://CN=Finance Employees,OU=Finance,DC=fabrikam,DC=com")

i = 0

For Each strUser in objGroup.Member
    i = i + 1
Next

Wscript.Echo "Total members in the group: " & i
Wscript.Echo

The preceding script does, indeed, echo back the number of members in a group. So why didn’t we just give you that script and call it good? Well, in light of the controversy surrounding the doctored photo, we decided to go the extra step and echo back not only the number of members in a group, but also a tally of the type of group member, like so:

Total members in the group: 840

group: 5
contact: 595
user: 240

That’s just our way of trying to make amends for all the heartache and heartbreak that has no doubt accompanied the doctored photo scandal. Use whichever script best suits your needs, and with our compliments.

As for the original script (the fancy one), that one kicks off by connecting to the group in question, in this case a group named Finance Employees, housed in the Finance OU of fabrikam.com:

Set objGroup = GetObject("LDAP://CN=Finance Employees,OU=Finance,DC=fabrikam,DC=com")

After we make a connection to the group account in Active Directory, we set the value of a counter variable named i to 1; we’ll use this variable to tally the number of members in the group. From there we then create an instance of the Scripting.Dictionary object, the object we’ll use to keep track of the different member types (like user, contact, and group):

Set objDictionary = CreateObject("Scripting.Dictionary")

That brings us to this line of code:

For Each strUser in objGroup.Member

As it turns out, Active Directory groups all have a multi-valued property named Member; this property contains a collection of all the members of that group. In order to get at the group membership all we have to do is set up a For Each loop to loop through all the values stored in the Member property.

Which, coincidentally enough, is exactly what we did in our script.

Inside the loop the first thing we do is increment the value of our counter variable. Each time we go through the loop we increment the value of i. Why? Well, suppose we have 37 members in the group. In that case, we’re going to run through the loop 37 times; when we exit the loop, i will be equal to 37. Which, now that we think about it, means that i will thus be able to tell us how many members are in the group.

Was that lucky or what?

As you may or may not know, individual group members are listed in the Member attribute by distinguished name (e.g., CN= Ken Myer, OU=Finance, dc=fabrikam, dc=com). Is that useful? You bet it is; that means we can bind to the individual member account using the following line of code:

Set objMember = GetObject("LDAP://" & strUser)

Why do we even want to bind to the individual member account? Well, in addition to keeping a simple tally of the number of members in the group, we want to determine the member type; the only way to do that is to bind to the account and retrieve the value of the Class property. That’s what we do here:

strType = objMember.Class

At this point we know that the group member is a user (or a contact or a group or whatever). But now what? Well, as we noted, we’re going to use our Dictionary object to keep a running tally of member types. With that in mind, our next step is to check and see whether this particular member type is already in the Dictionary:

If Not objDictionary.Exists(strType) Then

Suppose the preceding line of code comes back True; that means the member type is not in the Dictionary. (Notice the If Not syntax.) In that case, we use the following line of code to add the type to the Dictionary and set the value of the new item to 1:

objDictionary.Add strType, "1"

Got that? If not, you might want to take a look at the Microsoft Windows 2000 Scripting Guide for a more detailed look at the Dictionary object.

But what if the member type can be found in the Dictionary? That’s fine; if the member type already exists in the Dictionary then we simply use this line of code to increment the item value by 1:

objDictionary.Item(strType) = objDictionary.Item(strType) + 1

And then we loop around and repeat the process for the next member in the group.

After we’ve looped through the entire group membership we echo back the total number of members in the group (represented by our counter variable i), followed by a blank line:

Wscript.Echo "Total members in the group: " & i
Wscript.Echo

And then we set up a For Each loop to loop through all the items in the Dictionary, echoing back the member type and the item value:

For Each objType in objDictionary
    Wscript.Echo objType & ": " & objDictionary.Item(objType)
Next

And that, as you might expect, is that.

Oh, one more thing: if you’d like to count the number of members in a local group, use this script instead:

strComputer = "atl-fs-01"

i = 0

Set objGroup = GetObject("WinNT://" & strComputer & "/Administrators")

For Each strMember in objGroup.Members
    i = i + 1
Next

Wscript.Echo "Total members in the group: " & i

We won’t bother explaining how this script works, at least not today. But that’s OK; we have other sources of information that explain how to work with local groups.

Which brings us back around to the burning question of the day: are the Scripting Guys upset that someone submitted a doctored photo for publication in the Script Center? Well, to be honest, when it was pointed out to us, we thought it was kind of funny. (And, truth be told, it’s possible that we might have used a doctored photo or two ourselves.) So no, we’re not upset: if you want to take the trouble to create a doctored photo of Dr. Scripto, well, who are we to stop you?

Besides, there are even unsubstantiated rumors that Dr. Scripto himself isn’t real, that he’s just a piece of clip art. Is there any truth to those rumors? We don’t know. But you can bet that Jean Ross and her Delta Scripting Force will find out.

Just as soon as they finish those doughnuts they liberated from the kitchen.

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • So can we use this script to output to a CSV with groups in an OU and how many users are in each group?  How would we go about that?

    Thanks.

  • For just a simple search using joeware.net (free tool) adfind you can... Copy the below into a batch file and execute with adfind.exe in the same directory.

    -------------------------------------------------------------------------------------------------------------------------

    for /f "delims=" %%i in ('adfind -default -rb ou^=groups -f objectclass^=group distinguishedName -list') do (

    for /f %%b in ('adfind -list -c -f ^"memberof^=%%i^" -c') do echo "%%i",%%b>> allgroupscount.csv

    )

    -------------------------------------------------------------------------------------------------------------------------

    Explanation of Above (remarked out for my batch file.)

    rem del d:\sharetest\allgroupscount.csv removes old output file so data is not appended

    REm "delims=" ignores all delimiters (spaces) and reads entire line

    REm  %%i in ('adfind -default -rb ou^=groups -f objectclass^=group distinguishedName -list') passes the output of adfind to for loop

    REM do ( allows for mulit function call from for loop

    REM for /f %%b in ('adfind -list -c -f ^"memberof^=%%i^" -c') do echo "%%i",%%b>> d:\sharetest\allgroupscount.csv nested for loop that passes variables to csv file

    rem ) end of for loop multi call

    rem the caret symbol ^ is an escape character telling 'for' not to treat the following character as a control character.

  • Script does not totally work...what if group is over 1500 members? You need to page the results.

  • I want to count all members in all lists. How is this done?

  • thanks