Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I tell whether the member of a group is a user, a computer, or another group?

-- ON

SpacerHey, Scripting Guy! AnswerScript Center

Hey, ON. Interesting question and - to tell you the truth - one we’d never really thought about. It’s easy enough to list all the members of a group; for example, here’s a script that reports back all the members of the Finance Managers group:

Set objGroup = GetObject _
    ("LDAP://cn=Finance Managers, ou=Finance, dc=fabrikam, dc=com")

For Each strUser on objGroup.Member
        Wscript.Echo strUser
Next

When you run this script you’ll get back the value of the distinguishedName (DN) attribute for each member of the group; that output will look something like this:

cn=atl-ws-01, ou=Finance, dc=fabrikam, dc=com
cn=Ken Myer, ou=Finance, dc=fabrikam, dc=com
cn=North American Finance Users, ou=Finance, dc=fabrikam, dc=com
cn=Pilar Ackerman, ou=Finance, dc=fabrikam, dc=com

So what’s wrong with that? Well, nothing, except that - depending on your naming conventions - it might be difficult to look at the list and determine whether a group member is a user, a computer, or even another group. Likewise, your script might be designed to take specific action based on the item type; for example, if a group member happens to be another group you might want to use a recursive function to connect to and list the members of that group. But you can’t do that unless you can first determine whether or not the member actually is another group.

So how can we distinguish users from computers and groups from whatever? As it turns out all Active Directory objects have an attribute named Class. (Yes, in Active Directory even the Scripting Guys have Class!) The Class attribute can tell you what kind of object you’re dealing with: a user, a computer, a group, whatever. To tell the difference all you have to do is examine the value of the Class attribute.

Of course, there is one tiny catch. When you enumerate group members the only attribute you get back is the member’s distinguished name; you don’t get back the Class attribute. That means you can’t just enumerate group members and their Class types. Instead, you need to bind to each individual group member’s Active Directory account and then echo back the value of the Class attribute. But don’t worry; that’s very easy.

Let’s take a look at a script that reports back group membership and Class types for the Finance Managers group:

Set objGroup = GetObject _
    ("LDAP://cn=Finance Managers, ou=Finance, dc=fabrikam, dc=com")

For Each strUser on objGroup.Member
    Set objMember = GetObject("LDAP://" & strUser)
    Wscript.Echo objMember.CN & ", " & objMember.Class
Next

What did we tell you: just a few lines of code and we’re done. We begin by binding to the Finance Managers group in Active Directory. After making the connection we use a simple For Each loop to loop through all the values in the multi-valued attribute Member. Because Member just happens to contain the distinguished names of all the members of the group, looping through these values will…well, give us the distinguished names of all the members of the group.

And before you ask, yes, the attribute name probably should be Members, with an s on the end. But it’s not; go figure.

Now, if all we wanted was the DN for each group member we’d be done. However, we need to get the value of the Class attribute as well. Therefore, inside our For Each loop we bind to the Active Directory account of each group member. That’s what we do with this line of code:

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

To bind to an Active Directory object you need to specify the object’s ADsPath. The ADsPath consists of the ADSI provider name (for Active Directory that will always be LDAP://) followed by the object’s distinguished name. We already have the DN; that’s stored in the variable strUser. Consequently, all we have to do is concatenate LDAP:// with the value of strUser, and pass that value to the GetObject method. In turn, GetObject will bind us to the Active Directory account.

Make sense? Good.

After we’re connected to the account we can echo back the values of any attributes belonging to that account. In our sample script we simply echo back the value of the CN and Class attributes (with a comma to separate them); that gives us output similar to this:

atl-ws-01, computer
Ken Myer, user
North American Finance Users, group
Pilar Ackerman, user

There you have it: output that distinguishes between classes such as users, computers, and groups. No one ever believes us when we say a scripting task is easy, but this time we have proof!