Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I check to see if a user is in both group A and group B and, if so, add that user to Group C?

-- DH

SpacerHey, Scripting Guy! AnswerScript Center

Hey, DH. Good heavens, how are we supposed to know that?!? Sheesh.

Sorry; we just always wanted to say that. Now that we have that out of our system, here’s a sample script that checks to see if Ken Myer belongs to both the Finance Users and the Fabrikam Managers groups in Active Directory. If he does belong to both groups, then the script adds him to a third group, Finance Managers (if A and B, then C):

On Error Resume Next

Set objUser = GetObject("LDAP://cn=Ken Myer,ou=Finance,dc=fabrikam,dc=com")

i = 0

For Each strGroup in objUser.memberOf
    Set objGroup = GetObject("LDAP://" &  strGroup)
    If objGroup.CN = "Finance Users" Then
        i = i + 1
    End If
    If objGroup.CN = "Fabrikam Managers" Then
        i = i + 1
    End If
Next

If i = 2 Then
    Set objGroup = GetObject("LDAP://cn=Finance Managers,ou=Finance,dc=fabrikam,dc=com")
    objGroup.Add(objUser.ADsPath)
End If

The script begins by creating an object reference to the Ken Myer user account in Active Directory. We then assign the value 0 to a counter variable named i; we’ll use this variable to keep track of how many of our two target groups Ken belongs to.

As it turns out, group membership in Active Directory is stored in a multi-valued attribute named memberOf. With that in mind, we use this line of code to walk through the collection of groups that Ken Myer is a member of:

For Each strGroup in objUser.memberOf

As it further turns out, the memberOf attribute returns the distinguished name of each group Ken Myer belongs to. That’s nice, but the distinguished name looks something like this:

cn=Finance Users,ou=Finance,dc=fabrikam,dc=com

Needless to say, we’re used to dealing with groups by name (e.g., Finance Users); most likely we have no idea where the group account is stored in Active Directory. Therefore, we don’t even bother checking the distinguished name; instead, we use that value to connect to the group account itself. That’s what we do here:

Set objGroup = GetObject("LDAP://" &  strGroup)

Once we connect to the group account we can then use code like this to check the name (CN) of the group, something a bit easier and a bit more intuitive:

If objGroup.CN = "Finance Users" Then

As we loop through the groups, we’re checking to see if any of those groups have a CN equal to Finance Users (one of our two target groups). What if one of those groups does have a CN equal to Finance Users? Well, in that case we increment the value of i by 1:

i = i + 1

Pretty fancy coding, huh?

Meanwhile, we have a similar block of code that checks to see if the group has a CN equal to Fabrikam Managers. If it does, then we again increment the value of our counter variable by 1:

If objGroup.CN = "Fabrikam Managers" Then
    i = i + 1
End If

We then loop around and check the next group in the collection.

Why do we increment the value of our counter variable? Well, if Ken doesn’t belong to either of our target groups then i will never be changed and will thus equal 0. If Ken belongs to one group, but not the other, then i will be changed one time, and thus be equal to 1. So what does it mean if i is equal to 2? You got it: Ken must be a member of both Finance Users and Fabrikam Managers (because the value if i was incremented twice). Consequently, we want to add Ken to our third group, Finance Managers:

If i = 2 Then
    Set objGroup = GetObject("LDAP://cn=Finance Managers,ou=Finance,dc=fabrikam,dc=com")
    objGroup.Add(objUser.ADsPath)
End If

Nothing too fancy here: we create an object reference to the Finance Managers group, then use the Add method to add Ken Myer. Note that when calling the Add method we pass the value objUser.ADsPath: that’s the ADsPath to the Ken Myer user account in Active Directory.

Two quick notes regarding this script. First, it’s possible that you could have multiple groups with the same CN; if that’s the case, then examining the value of the CN attribute won’t do you much good. Instead, you’ll need to look at the sAMAccountName attribute, which must be unique within the domain. (Of course, the sAMAccountName is going to be something along the lines of fabmgrs, another value you typically don’t know off the top of your head.)

Second, this script doesn’t deal with nested groups: if Ken is a member of a group which is a member of a group which is a member of Fabrikam Managers, well, then Ken is also a member of Fabrikam Managers. However, this script doesn’t deal with situations like that. Why? Because nested groups can get a bit messy, and they require a level of explanation that lies outside the scope of this column. However, you can find a sample script (and an accompanying explanation) for dealing with nested groups in this Scripting Guys Webcast.