[Sample of Mar 2nd] Get User Group Membership in AD
![]() |
![]() |
|
![]() |
![]() |
Sample download: https://code.msdn.microsoft.com/VBGetUserGroupInAD-a94dc080
Today’s code sample illustrates how to perform a search on the user’s group membership in Active Directory. This demonstrates the recursive looping method. Also it shows how to get the Object SID for the group. The sample was written by Microsoft Support Escalation Engineer Shaleen Thapa.
You can find more code samples that demonstrate the most typical programming scenarios by using Microsoft All-In-One Code Framework Sample Browser or Sample Browser Visual Studio extension. They give you the flexibility to search samples, download samples on demand, manage the downloaded samples in a centralized place, and automatically be notified about sample updates. If it is the first time that you hear about Microsoft All-In-One Code Framework, please watch the introduction video on Microsoft Showcase, or read the introduction on our homepage https://1code.codeplex.com/.
Introduction
This sample application demonstrates how to perform a search on the user’s group membership in Active Directory. This demonstrates the recursive looping method. Also it shows how to get the Object SID for the group
Running the Sample
You can execute this sample by creating the exe via Visual Studio.
In order to execute the application, you must need to consider the followings:
- Please change the distingusihedName of the domain as per your domain environment. This you should find at the line# 31 in the file VBGetUserGroupInAD.VB. Currently it is using DC=contoso,DC=com
- Please pass the appropriate user’s sAMAccountName as the second parameter, for which we are searching the group membership in AD
Using the Code
We are using System.DirectoryServices namespace to perform a search on AD. We will be passing the distinguishedName of the domain with the username whose membership we would like to fetch.
Once we found the user, we will read the memberOF attribute’s value. It is one of the possibilities that the group can be member of another group as well; in this case we would need to do a recursive looping.
''' <summary>
''' This function will search the user.
''' Once user is found, it will get it's memberOF attribute's value.
''' </summary>
''' <param name="domainDN">distinguishedName of the domain</param>
''' <param name="sAMAccountName">
''' sAMAccountName of the user for which we are searching the group membership in AD
''' </param>
''' <returns></returns>
''' <remarks></remarks>
Public Function GetUserGroups(ByVal domainDN As String, ByVal sAMAccountName As String) As List(Of String)
Try
'Create the DirectoryEntry object to bind the distingusihedName of your domain
Using rootDE As New DirectoryEntry("LDAP://" & domainDN)
'Create a DirectorySearcher for performing a search on abiove created DirectoryEntry
Using dSearcher As New DirectorySearcher(rootDE)
'Create the sAMAccountName as filter
dSearcher.Filter = "(&(sAMAccountName=" & sAMAccountName & ")(objectClass=User)(objectCategory=Person))"
dSearcher.PropertiesToLoad.Add("memberOf")
dSearcher.ClientTimeout.Add(New TimeSpan(0, 20, 0))
dSearcher.ServerTimeLimit.Add(New TimeSpan(0, 20, 0))
'Search the user in AD
Dim sResult As SearchResult = dSearcher.FindOne
If sResult Is Nothing Then
Throw New ApplicationException("No user with username " & sAMAccountName & " could be found in the domain")
Else
Dim lGroups As New List(Of String)
'Once we get the userm let us get all the memberOF attibute's value
For Each grp In sResult.Properties("memberOf")
Dim sGrpName As String = CStr(grp).Remove(0, 3)
'Bind to this group
Dim deTempForSID As New DirectoryEntry("LDAP://" + grp.ToString().Replace("/", "\/"))
Try
deTempForSID.RefreshCache()
'Get the objectSID which is Byte array
Dim objectSid As Byte() = DirectCast(deTempForSID.Properties("objectSid").Value, Byte())
'Pass this Byte array to Security.Principal.SecurityIdentifier to convert this
'byte array to SDDL format
Dim SID As New System.Security.Principal.SecurityIdentifier(objectSid, 0)
If sGrpName.Contains(",CN") Then
sGrpName = sGrpName.Remove(sGrpName.IndexOf(",CN"))
ElseIf sGrpName.Contains(",OU") Then
sGrpName = sGrpName.Remove(sGrpName.IndexOf(",OU"))
End If
'Perform a recursive search on these groups.
RecursivelyGetGroups(dSearcher, lGroups, sGrpName, SID.ToString())
Catch ex As Exception
Console.WriteLine("Error while binding to path : " + grp.ToString())
Console.WriteLine(ex.Message.ToString())
End Try
Next
Return lGroups
End If
End Using
End Using
Catch ex As Exception
Console.WriteLine("Please check the distinguishedName of the domain if it is as per your domain or not?")
Console.WriteLine(ex.Message.ToString())
End
End Try
End Function
''' <summary>
''' This function will perform a recursive search and will add only one occurance of
''' the group found in the enumeration.
''' </summary>
''' <param name="dSearcher">DirectorySearcher object to perform search</param>
''' <param name="lGroups">List of the Groups from AD</param>
''' <param name="sGrpName">
''' Group name which needs to be checked inside the Groups collection
''' </param>
''' <param name="SID">objectSID of the object</param>
''' <remarks></remarks>
Public Sub RecursivelyGetGroups(ByVal dSearcher As DirectorySearcher, ByVal lGroups As List(Of String), ByVal sGrpName As String, ByVal SID As String)
'Check if the group has already not found
If Not lGroups.Contains(sGrpName) Then
lGroups.Add(sGrpName & " : " & SID)
'Now perform the search based on this group
dSearcher.Filter = "(&(objectClass=grp)(CN=" & sGrpName & "))".Replace("\", "\\")
dSearcher.ClientTimeout.Add(New TimeSpan(0, 2, 0))
dSearcher.ServerTimeLimit.Add(New TimeSpan(0, 2, 0))
'Search this group
Dim GroupSearchResult As SearchResult = dSearcher.FindOne
If Not GroupSearchResult Is Nothing Then
For Each grp In GroupSearchResult.Properties("memberOf")
Dim ParentGroupName As String = CStr(grp).Remove(0, 3)
'Bind to this group
Dim deTempForSID As New DirectoryEntry("LDAP://" + grp.ToString().Replace("/", "\/"))
Try
'Get the objectSID which is Byte array
Dim objectSid As Byte() = DirectCast(deTempForSID.Properties("objectSid").Value, Byte())
'Pass this Byte array to Security.Principal.SecurityIdentifier to convert this
'byte array to SDDL format
Dim ParentSID As New System.Security.Principal.SecurityIdentifier(objectSid, 0)
If ParentGroupName.Contains(",CN") Then
ParentGroupName = ParentGroupName.Remove(ParentGroupName.IndexOf(",CN"))
ElseIf ParentGroupName.Contains(",OU") Then
ParentGroupName = ParentGroupName.Remove(ParentGroupName.IndexOf(",OU"))
End If
RecursivelyGetGroups(dSearcher, lGroups, ParentGroupName, ParentSID.ToString())
Catch ex As Exception
Console.WriteLine("Error while binding to path : " + grp.ToString())
Console.WriteLine(ex.Message.ToString())
End Try
Next
End If
End If
End Sub
More Information
For more information on System.DirectoryServices Namespace https://msdn.microsoft.com/en-us/library/system.directoryservices.aspx , DirectoryEntry Class https://msdn.microsoft.com/en-us/library/system.directoryservices.directoryentry.aspx & DirectorySearcher Class https://msdn.microsoft.com/en-us/library/system.directoryservices.directorysearcher.aspx
For System.Security.Principal.SecurityIdentifier https://msdn.microsoft.com/en-us/library/system.security.principal.securityidentifier.aspx
Comments
- Anonymous
June 20, 2012
The comment has been removed - Anonymous
November 26, 2013
I know this is old post but I am getting same error. do you every got resolution for this one? Thanks, Tapan