Microsoft KB Archive/301916

= How to enumerate a user's security group membership using Visual Basic or Visual Basic Script =

Article ID: 301916

Article Last Modified on 1/15/2007

-

APPLIES TO


 * Microsoft Active Directory Service Interfaces 2.5
 * Microsoft Active Directory Service Interfaces 2.5

-



This article was previously published under Q301916



SUMMARY
This article describes a method for enumerating the security groups that a user is a member of by using Microsoft Visual Basic or Microsoft Visual Basic Script (VBScript). The method described here does not enumerate the local security groups and will not work across foreign forests.



MORE INFORMATION
The tokenGroups property of an Active Directory (AD) user object contains the binary security identifiers (SIDs) of all of the security groups that a user is a member of. This property is a constructed attribute, which means that the property is created on the client by the provider and not stored as data in the AD.

An alternate approach is to read the MemberOf attribute, which is an enumeration of the immediate groups, including both security and distribution groups. The MemberOf attribute does not enumerate the nested groups. The best approach for performing security group enumeration is to go through the security infrastructure and use the security APIs, but these APIs cannot be called directly from Visual Basic or VBScript. For more information on these alternate solutions, see the &quot;References&quot; section of this article.

Converting SIDs from binary to a human-readable form
The SID for the group is stored in its binary form in the TokenGroups attribute. This form is not human-readable nor can it be used to bind to the group object. The SID must be converted if you want to use it to bind to an object.

The IADsSID object that is exported by ADsSecurity.dll can be used in a Visual Basic program to convert the binary SID into a Security Account Manager (SAM) account name or a Lightweight Directory Access Protocol (LDAP) DN. Unfortunately, the IADsSID object cannot be used from a Visual Basic Script. &quot;Using IADsSID from Visual Basic to Resolve a Binary SID into a String,&quot; which follows this section, contains a Visual Basic code snippet that uses the IADsSID object to convert the binary SID into a string.

A Visual Basic Script solution involves the use of the Array Converter sample (see the &quot;References&quot; section). The ADs.ArrayConvert object can be used to convert the binary SID into a hexstring. From this hexstring, an LDAP SID bind string can be created. By using the SID bind string, you can obtain the group object from the AD. The section &quot;Using ADs.ArrayConvert from Visual Basic Script to Build an SID Bind String,&quot; following in this article, contains a Visual Basic Script example that illustrates how to use the ADs.ArrayConvert object to create an SID bind string.

Using IADsSID from Visual Basic to resolve a binary SID into a string
ADsSecurity.dll must be registered on the client through the use of Regsvr32 before you cans use the IADsSID object. In the Visual Basic project references, the ADsSecurity 2.5 Type Library and the Active DS Type Library must be selected. Dim oSid As New ADsSID Dim oUsr As IADsUser Dim oGrp As IADs Set oUsr = GetObject(&quot;LDAP_ADsPATH_TO_A_ACTIVE_DIRECTORY_OBJECT&quot;) oUsr.GetInfoEx Array(&quot;TokenGroups&quot;), 0 grps = oUsr.Get(&quot;tokenGroups&quot;) For Each grp In grps oSid.SetAs ADS_SID_RAW, grp Debug.Print oSid.GetAs(ADS_SID_SAM) Next grp

Using ADs.ArrayConvert from Visual Basic Script to build an SID bind string
In order for this code snippet to function correctly, the ADS.dll must be registered on the client (see &quot;References&quot;). set args = WScript.Arguments if ( args.Count < 1 ) then WScript.Echo &quot;ERROR: Wrong number of arguments.&quot; WScript.Echo &quot;USAGE: tokengroups LDAP_ADsPath&quot; WScript.Echo &quot;WHERE: LDAP_ADsPath is the LDAP ADsPath of a user object in the domain&quot; WScript.Echo WScript.Echo &quot;NOTE: This script requires that ADs.DLL be registered on the client&quot; WScript.Echo &quot;In order to convert the binary SID into a form that can be used in a &quot; WScript.Echo &quot;bind string. See KB Q250344&quot; WScript.Echo WScript.quit end if set obj = GetObject( args(0) ) obj.GetInfoEx ARRAY(&quot;tokengroups&quot;),0 grps = obj.Get(&quot;tokengroups&quot;) set oCvrt = CreateObject(&quot;ADs.ArrayConvert&quot;) wscript.echo &quot;Created sidobj&quot; for k = lbound(grps) to ubound(grps) b = grps(k) hexSid = oCvrt.CvOctetStr2vHexStr( b ) bindSid = &quot;LDAP://&quot; WScript.Echo bindSid set oVal = GetObject(bindSid) WScript.Echo oVal.Get(&quot;cn&quot;) set oVal = Nothing next

