Looping through members of a group in VBScript

Looping through members of a group in VBScript

Post by Alex Burd » Sat, 19 Jan 2002 02:20:56



Is there a way other than a For.. Each loop to loop through members of a
group in VBScript?

Any help would be appreciated.
Thanks,
Alex

 
 
 

Looping through members of a group in VBScript

Post by Max L. Vaug » Sun, 20 Jan 2002 01:38:57


That all depends.  Are you looking for a user's security groups? Distribution Groups? or Univiersal groups?

If you are working with Security Groups for a user on a Win2k domain, the LDAP provider does something that is very cool.  There is an attribute on the user
object called TokenGroups.  It is a constructed attribute that contains all of the SIDs for the security groups a user is a member of.  If you know the Groups
SID, you can then compare it to the list of SIDs provided in TokenGroups and determine if the user is a member of that group.  The neat thing is that this
attribute contains ALL security groups the user is a member of, including nested groups.

The following KB provides an example of how to enumerate the TokenGroups collection:
http://support.microsoft.com/support/kb/Articles/q301/9/16.asp

I have included a simple VBS that illustrates how to use the TokenGroups attribute to test for group membership.  Since VBS does not handle arrays of
bytes, I was forced to convert the SID into another form to test for equality.  In VB,  you can write code to walk the arrays and test each element, eliminating
the need for any additional DLLs.  

If you are looking at group membership that is not part of the Security Groups, like distribution and Universal groups, then you are left with using the
MemberOf collection and walking each group in succession to find nested groups ( Possible on Win2k Native Mode Domains only).  This is a very network
intensive process because you must bind to each group object and walk the MemberOf collection.

Sincerely,
Max Vaughn [MS]
Microsoft Developer Support

Disclaimer: This posting is provided "AS IS" with no warranties, and confers no rights. You assume all risk for your use.

<<<<<<<<<<  Simple VBS to test group membership using the TokenGroups attribute>>>>>>>>>
'+++++++++++++++++++++++++++++++++++++++++++++
Function CmpArray( Src, Cmpa)
'
' Test the size of the arrays...
'
Ssize = UBOund(src) - LBound(src)
Scmp = UBound(Cmpa) - LBound(cmpa)
CmpArray = FALSE
if( SSize = Scmp ) then
  '
  ' Sizes match, lets use the
  ' ADS.DLL to convert the octet string into
  ' a hex string, then we will compare the hex strings
  ' to see if they are equal.
  '
  ' kb Q301916 describes how to build ADS.DLL
  '
  Dim oADs : Set oADs = CreateObject("ADs.ArrayConvert")
  CmpArray = TRUE
  strCmpa = oADs.CvOctetStr2vHexStr(cmpa)
  strSrc = oADs.CvOctetStr2VHexStr(src)
  if( strcmpa <> strSrc ) then
    '
        ' Don't match,
        ' Return FALSE
        '
    CmpArray = FALSE
  end if
End If
end function
'-----------------------------------------------------------------
dim oGrp
dim oUsr
dim oArgs : set oArgs = WScript.Arguments
if( oArgs.Count < 2 ) then
  WScript.Echo "Script requires two arguements,"
  WScript.Echo "first Arg is LDAP AdsPath of a user"
  WScript.Echo "Second Arg is LDAP path of a group"
  WScript.Echo VBcRlf & "Script will tell you if the user is a member of the group"
  WScript.Echo "Script will test all nested security groups on a Win2k Native Mode Domain"
  Wscript.quit 0
end if
'
' Open the group...
'
set oGrp = GetObject(oArgs(1))
set oUsr = GetObject(oArgs(0))
'
' Request the TokenGroups....
' Contains all of the SIDs for the security groups in the
' user is a member of in the domain
'
oUsr.GetInfoEx ARRAY("TokenGroups"), 0
grpSIDs = oUsr.Get("TokenGroups")
'
' Now, get the groups SID
'
grpSID = oGrp.Get("ObjectSID")
'
' Now, compare....
'
for each oSd in grpSIDs
  if( CmpArray( oSD, grpSID ) ) then
    WScript.Echo "Yes, " & oUsr.Get("CN")
        WScript.Echo "a member of group " & oGrp.Get("CN")
        wScript.quit 0
  end if
next
WScript.Echo "Not in the group..."

 
 
 

Looping through members of a group in VBScript

Post by Alex Burd » Sun, 20 Jan 2002 03:13:25


Max,

Thanks for your help. I'm actually looking for a way to loop through the
Group.Members collection. All the code samples that I have seen use a For
Each loop to do it. The problem that I have is that a piece of VB code (it
was originally in VBS, but i rewrote it in VB to isolate on this piece)
(sample below) works for one group and doesn't work for another group. The
For Each loop never executes even though the count returned is 33. So I want
to try and rewrite this code to use some different technique.

Dim memberlist As IADsMembers
Set memberlist = grp.Members
MsgBox memberlist.Count
Dim member As IADs
For Each member In memberlist
    MsgBox member.Name
Next

Any suggestions would be greatly appreciated.
Thanks,
Alex



Quote:> That all depends.  Are you looking for a user's security groups?

Distribution Groups? or Univiersal groups?
Quote:

> If you are working with Security Groups for a user on a Win2k domain, the

LDAP provider does something that is very cool.  There is an attribute on
the user
Quote:> object called TokenGroups.  It is a constructed attribute that contains

all of the SIDs for the security groups a user is a member of.  If you know
the Groups
Quote:> SID, you can then compare it to the list of SIDs provided in TokenGroups

and determine if the user is a member of that group.  The neat thing is that
this
Quote:> attribute contains ALL security groups the user is a member of, including
nested groups.

> The following KB provides an example of how to enumerate the TokenGroups
collection:
> http://support.microsoft.com/support/kb/Articles/q301/9/16.asp

> I have included a simple VBS that illustrates how to use the TokenGroups

attribute to test for group membership.  Since VBS does not handle arrays of
Quote:> bytes, I was forced to convert the SID into another form to test for

equality.  In VB,  you can write code to walk the arrays and test each
element, eliminating
Quote:> the need for any additional DLLs.

> If you are looking at group membership that is not part of the Security

Groups, like distribution and Universal groups, then you are left with using
the
Quote:> MemberOf collection and walking each group in succession to find nested

groups ( Possible on Win2k Native Mode Domains only).  This is a very
network
Quote:> intensive process because you must bind to each group object and walk the

MemberOf collection.
Quote:

> Sincerely,
> Max Vaughn [MS]
> Microsoft Developer Support

> Disclaimer: This posting is provided "AS IS" with no warranties, and

confers no rights. You assume all risk for your use.
Quote:

> <<<<<<<<<<  Simple VBS to test group membership using the TokenGroups
attribute>>>>>>>>>
> '+++++++++++++++++++++++++++++++++++++++++++++
> Function CmpArray( Src, Cmpa)
> '
> ' Test the size of the arrays...
> '
> Ssize = UBOund(src) - LBound(src)
> Scmp = UBound(Cmpa) - LBound(cmpa)
> CmpArray = FALSE
> if( SSize = Scmp ) then
>   '
>   ' Sizes match, lets use the
>   ' ADS.DLL to convert the octet string into
>   ' a hex string, then we will compare the hex strings
>   ' to see if they are equal.
>   '
>   ' kb Q301916 describes how to build ADS.DLL
>   '
>   Dim oADs : Set oADs = CreateObject("ADs.ArrayConvert")
>   CmpArray = TRUE
>   strCmpa = oADs.CvOctetStr2vHexStr(cmpa)
>   strSrc = oADs.CvOctetStr2VHexStr(src)
>   if( strcmpa <> strSrc ) then
>     '
> ' Don't match,
> ' Return FALSE
> '
>     CmpArray = FALSE
>   end if
> End If
> end function
> '-----------------------------------------------------------------
> dim oGrp
> dim oUsr
> dim oArgs : set oArgs = WScript.Arguments
> if( oArgs.Count < 2 ) then
>   WScript.Echo "Script requires two arguements,"
>   WScript.Echo "first Arg is LDAP AdsPath of a user"
>   WScript.Echo "Second Arg is LDAP path of a group"
>   WScript.Echo VBcRlf & "Script will tell you if the user is a member of
the group"
>   WScript.Echo "Script will test all nested security groups on a Win2k
Native Mode Domain"
>   Wscript.quit 0
> end if
> '
> ' Open the group...
> '
> set oGrp = GetObject(oArgs(1))
> set oUsr = GetObject(oArgs(0))
> '
> ' Request the TokenGroups....
> ' Contains all of the SIDs for the security groups in the
> ' user is a member of in the domain
> '
> oUsr.GetInfoEx ARRAY("TokenGroups"), 0
> grpSIDs = oUsr.Get("TokenGroups")
> '
> ' Now, get the groups SID
> '
> grpSID = oGrp.Get("ObjectSID")
> '
> ' Now, compare....
> '
> for each oSd in grpSIDs
>   if( CmpArray( oSD, grpSID ) ) then
>     WScript.Echo "Yes, " & oUsr.Get("CN")
> WScript.Echo "a member of group " & oGrp.Get("CN")
> wScript.quit 0
>   end if
> next
> WScript.Echo "Not in the group..."

 
 
 

Looping through members of a group in VBScript

Post by Max L. Vaug » Wed, 23 Jan 2002 23:43:18


It is important to remember, that when the enumeration occurs, the provider attempts to return and IADs  interface for the object, that means that a bind is being
performed on the object.  If for some reason you cannot bind to the object, then the enumeration will stop without any type of error being created.  However, if
you look at the Member attribute of the group, this will return a multi-valued array of CNs for the group members.

dim oGrp
set oGrp = GetObject("LDAP_PATH_TO_GROUP")
mems = oGrp.GetEx("member")
for each item in mems
  WScript.Echo mem
next

Give that a try....

Sincerely,
Max Vaughn [MS]
Microsoft Developer Support

Disclaimer: This posting is provided "AS IS" with no warranties, and confers no rights. You assume all risk for your use.

 
 
 

Looping through members of a group in VBScript

Post by Alex Burd » Thu, 24 Jan 2002 07:48:02


Max,

Thanks a lot for your help. I figured out the problem. One of the Users in
the Group that I was querying had a disabled profile so I guess the
enumeration was not occurring.

Alex



Quote:> It is important to remember, that when the enumeration occurs, the

provider attempts to return and IADs  interface for the object, that means
that a bind is being
Quote:> performed on the object.  If for some reason you cannot bind to the

object, then the enumeration will stop without any type of error being
created.  However, if
Quote:> you look at the Member attribute of the group, this will return a

multi-valued array of CNs for the group members.
Quote:

> dim oGrp
> set oGrp = GetObject("LDAP_PATH_TO_GROUP")
> mems = oGrp.GetEx("member")
> for each item in mems
>   WScript.Echo mem
> next

> Give that a try....

> Sincerely,
> Max Vaughn [MS]
> Microsoft Developer Support

> Disclaimer: This posting is provided "AS IS" with no warranties, and

confers no rights. You assume all risk for your use.

- Show quoted text -

 
 
 

1. Using hideDLMemberships, how to hide group members via VBScript?

I need to hide members of a distribution list so people cannot see who
belongs to which group.  Currently I can use the AD users and Computers GUI
you to run an Exchange Task on each group and select the 'Hide Membership'
task and this will successfully hide members of a group.  The downside to
this method is that you have to run this for each distrubution list group.
Using the GUI is not an option, I need to have a script do this since our
lists are destroyed and created everynight and it is simply not efficient to
hand do this everymorning on 200+ groups.

So far I am using the following code to Hide memberships without much
success.
----------------------------------------------------------------
ou.Filter = Array("group")
for each Group in ou
     ' Hide the group's memberships
     Group.Put "hideDLMembership", "TRUE"
    Group.SetInfo
next
----------------------------------------------------------------

After this code runs in ADSI Edit, if you look at the Exchange Task option
for a particular group, it will register that the group is now 'hidden' but
yet in the GAL, i can still see the members of this group!  How can this be?

Has anyone written a VBScript that uses this 'hideDLMembership' parameter to
successfully hide memebrships of a group?

thanks,

gabor

2. Create Windows help files from TeX documents

3. Global groups within group groups - how do i get member list

4. Info needed on overlays

5. Adding member to group with more than 1,000 members

6. Any FaceSpan Users?

7. List members of Local Group on Member Server

8. nt4 & w2k don't see each other

9. Enumeration of global groups member of another group...

10. Getting the list of groups in which a user/group is a member.

11. Getting the groups a user is a member of doesn't work for hierarchical groups

12. urgent: nested groups aren't in the members property of the parent group!

13. Changing Property Values thru VBScript