Troubleshooting group expansion problems with RMS

I've had many customers call and ask me why when they send a mail to a 'group' some of those users cannot open the message, while some of them can.

I wrote a script that I have them run that will give me some important information.

-I usually want to make sure that the group is  'Universal'. The groups must be universal when you have members from different domains, because universal group types are the only group type whos membership is replicated to the GC, and since RMS uses GC queries...you get the point. 

-I want to make sure that the group has an email address, since that is what RMS uses to find the group

-I want to make sure that 1, and only one group is assigned to this e-mail address.

-I want to make sure that 'all' of the GCs have the same membership. They should if the group is universal, but if there is replication issues, it may not.

Here is that script. Once again, use at your own risk, and for the love of God...add some error trapping and comments (my own laziness astounds me, but since these are my private batch of tools, I know how they work. I never planned on blogging them. :))

The syntax is script <Forest> <group email> <Search All GCs?>
>cscript FindGroup.vbs contoso nerds@contoso.com 0   ß Just finds the group and quits
>cscript FindGroup.vbs contoso nerds@contoso.com 1   ß Finds the group in every GC and quits

I usually just run it with the '0' option up front to check the easy stuff, like group type and membership. I'll only run it with the '1' option if everything with a 0 looks good, or if the customer needs proof that a non-universal group membership type does not replicate all of its members across GCs. 

(Can you tell I use to be on the ADSI team here?) ;)

-Jason

'**********************************************************
' FindGroup.vbs - "Can I get a witness!!!"
'********************************************************** 

Set Args = Wscript.Arguments

strForestName = Args(0)
strGroup=Args(1)
FindAll = Args(2)

'***Get all the GCs***'

set objRootDSE = GetObject("LDAP://" & strForestName & "/" & "RootDSE")
strADsPath = "<LDAP://" & objRootDSE.Get("configurationNamingContext") & ">;"
strFilter  = "(&(objectcategory=ntdsdsa)(options=1));"
strAttrs   = "distinguishedname;"
strScope   = "SubTree"

set objConn = CreateObject("ADODB.Connection")
objConn.Provider = "ADsDSOObject"
objConn.Open "Active Directory Provider"

set objRS = objConn.Execute(strADsPath & strFilter & strAttrs & strScope)
If FindAll = 1 Then
objRS.MoveFirst
Else
objRS.MoveLast
End If

'***Get relative info from the group in question***

Do until objRS.EOF
    set objNTDS = GetObject("LDAP://" & objRS.Fields("distinguishedname").Value)
    set objServer = GetObject( objNTDS.Parent )
    strGC =  objServer.Get("dNSHostName")
 Wscript.Echo "Connecting to " & strGC & " ..."
 set objRSGroup = objConn.Execute("<GC://" & strGC & ">;(|(proxyaddresses=smtp:" & strGroup & _
                            ")(mail=" & strGroup & "));adspath;subtree")
 
 Wscript.Echo "Found " & objRSGroup.RecordCount & " group(s) matching that name."

 Do Until objRSGroup.EOF
   Set objGroup = GetObject(objRSGroup.Fields("adspath").Value)
   If objGroup.GroupType AND &h2 Then
    strGroupType = "Global"
   Else If  objGroup.GroupType AND &h4 Then
    strGroupType = "Domain Local"
   Else If objGroup.GroupType AND &h8 Then
    strGroupType = "Universal"
   End If
   End If
   End If
   If objGroup.GroupType AND &h80000000 Then
    strGroupType = strGroupType & " Security Group"
   Else
    strGroupType = strGroupType & " Distribution Group"
   End If
   Wscript.Echo "Group Name:" & objGroup.Name
  Wscript.Echo "Group Member Count:" & objGroup.Members.Count
  Wscript.Echo "Group Type:" & strGroupType
   For each mem in objGroup.members
    strName = mem.Get("name")
    strMail = mem.Get("mail")
    If strMail = "" Then
      Wscript.Echo strName & " has no email address."
    Else
      Wscript.Echo strName & ": " & strMail
    End If
   Next
  Wscript.Echo
 
  objRSGroup.MoveNext
 Loop
    objRS.MoveNext
Loop

Wscript.Echo "Done"