none
Active Directory - Find User In A Group

    Question

  • I have some code that checks user authetication in a windows .VB .NET 2008 program.

    We have 5 plants, each with its own HR plant department. Each plant has
    an AD group called "HR-Plant1", "HR-Plant2" ect. with its user/members.

    I'm looking for some code that will take the windows user name, check to see if that
    user is in a certain plants group and then let him into that form. We would then
    dump the need for the user to login to authenticate.

    Each form reads data from there local SQL DB and we already have setup
    that in the app.config.

    In looking I couldnt seem to find any good code on passing in the group name into
    an AD query and verifying a single user is a member.

    Any samples welcome, thank you!

    Tuesday, August 18, 2009 8:26 PM

Answers

  • OK, here's some code going at it from the other direction and querying the Group membership:

        Public Sub ListADGroupMembers()
    
            Dim DirectoryRoot As New DirectoryEntry("LDAP://RootDSE")
            Dim DNC = DirectoryRoot.Properties("DefaultNamingContext")(0).ToString()
            Dim GroupName As String = "The group name goes here"
            Dim GroupMembers As System.Collections.Specialized.StringCollection = GetGroupMembers(DNC, GroupName)
    
            For Each Member As String In GroupMembers
                Console.WriteLine(Member)
            Next Member
    
        End Sub
    
        Public Function GetGroupMembers(ByVal strDomain As String, ByVal strGroup As String) As System.Collections.Specialized.StringCollection
    
            Dim GroupMembers As New System.Collections.Specialized.StringCollection()
    
            Try
                Dim DirectoryRoot As New DirectoryEntry("LDAP://" & strDomain)
                Dim DirectorySearch As New DirectorySearcher(DirectoryRoot, "(CN=" & strGroup & ")")
                Dim DirectorySearchCollection As SearchResultCollection = DirectorySearch.FindAll()
                For Each DirectorySearchResult As SearchResult In DirectorySearchCollection
                    Dim ResultPropertyCollection As ResultPropertyCollection = DirectorySearchResult.Properties
                    Dim GroupMemberDN As String
                    For Each GroupMemberDN In ResultPropertyCollection("member")
                        Dim DirectoryMember As New DirectoryEntry("LDAP://" & GroupMemberDN)
                        Dim DirectoryMemberProperties As System.DirectoryServices.PropertyCollection = DirectoryMember.Properties
                        Dim DirectoryItem As Object = DirectoryMemberProperties("sAMAccountName").Value
                        If Nothing IsNot DirectoryItem Then
                            GroupMembers.Add(DirectoryItem.ToString())
                        End If
                    Next GroupMemberDN
                Next DirectorySearchResult
            Catch ex As Exception
                Trace.Write(ex.Message)
            End Try
    
            Return GroupMembers
    
        End Function

    Paul ~~~~ Microsoft MVP (Visual Basic)
    • Marked as answer by msny Wednesday, August 19, 2009 7:33 PM
    Wednesday, August 19, 2009 12:21 PM

All replies

  • Anyone please?
    Wednesday, August 19, 2009 11:07 AM
  • There are a couple of ways to do this using the System.DirectoryServices namespace. The below code will actually dump out all the groups a user is a member of. It's an LDAP query so the results are represented as the distinguished name of each group. You should be able to parse out the group name for comparison.

    If you're looking for something different let me know. I may have some other code which offers a more direct approach.

            Dim RootDSE As New DirectoryServices.DirectoryEntry("LDAP://RootDSE")
            Dim DomainDistinguishedName As String = RootDSE.Properties("DefaultNamingContext").Value
            Dim ADEntry As New DirectoryServices.DirectoryEntry("LDAP://" & DomainDistinguishedName)
            Dim ADSearch As New System.DirectoryServices.DirectorySearcher(ADEntry)
    
            Dim ADSearchResult As System.DirectoryServices.SearchResult
            ADSearch.PropertiesToLoad.Add("memberOf")
            ADSearch.Filter = ("(samAccountName=" & System.Security.Principal.WindowsIdentity.GetCurrent.Name.Split("\"c)(1) & ")")
            ADSearch.SearchScope = SearchScope.Subtree
            ADSearch.PropertiesToLoad.Add("displayName")
            ADSearchResult = ADSearch.FindOne()
            Dim PropertyCount As Integer = ADSearchResult.Properties("memberOf").Count
            If Not IsNothing(ADSearchResult) Then
                Dim ADUser As DirectoryEntry = ADSearchResult.GetDirectoryEntry
                Console.WriteLine(ADUser.Properties("samAccountName").Value)
                Console.WriteLine(ADUser.Properties("displayName").Value)
                Dim PropertyCounter As Integer
                Dim GroupDistinguishedName As String
                Dim MemberOf As String
                For PropertyCounter = 0 To PropertyCount - 1
                    GroupDistinguishedName = CType(ADSearchResult.Properties("memberOf")(PropertyCounter), String)
                    Console.WriteLine(GroupDistinguishedName.ToString)
                Next
            End If



    Paul ~~~~ Microsoft MVP (Visual Basic)
    Wednesday, August 19, 2009 12:09 PM
  • OK, here's some code going at it from the other direction and querying the Group membership:

        Public Sub ListADGroupMembers()
    
            Dim DirectoryRoot As New DirectoryEntry("LDAP://RootDSE")
            Dim DNC = DirectoryRoot.Properties("DefaultNamingContext")(0).ToString()
            Dim GroupName As String = "The group name goes here"
            Dim GroupMembers As System.Collections.Specialized.StringCollection = GetGroupMembers(DNC, GroupName)
    
            For Each Member As String In GroupMembers
                Console.WriteLine(Member)
            Next Member
    
        End Sub
    
        Public Function GetGroupMembers(ByVal strDomain As String, ByVal strGroup As String) As System.Collections.Specialized.StringCollection
    
            Dim GroupMembers As New System.Collections.Specialized.StringCollection()
    
            Try
                Dim DirectoryRoot As New DirectoryEntry("LDAP://" & strDomain)
                Dim DirectorySearch As New DirectorySearcher(DirectoryRoot, "(CN=" & strGroup & ")")
                Dim DirectorySearchCollection As SearchResultCollection = DirectorySearch.FindAll()
                For Each DirectorySearchResult As SearchResult In DirectorySearchCollection
                    Dim ResultPropertyCollection As ResultPropertyCollection = DirectorySearchResult.Properties
                    Dim GroupMemberDN As String
                    For Each GroupMemberDN In ResultPropertyCollection("member")
                        Dim DirectoryMember As New DirectoryEntry("LDAP://" & GroupMemberDN)
                        Dim DirectoryMemberProperties As System.DirectoryServices.PropertyCollection = DirectoryMember.Properties
                        Dim DirectoryItem As Object = DirectoryMemberProperties("sAMAccountName").Value
                        If Nothing IsNot DirectoryItem Then
                            GroupMembers.Add(DirectoryItem.ToString())
                        End If
                    Next GroupMemberDN
                Next DirectorySearchResult
            Catch ex As Exception
                Trace.Write(ex.Message)
            End Try
    
            Return GroupMembers
    
        End Function

    Paul ~~~~ Microsoft MVP (Visual Basic)
    • Marked as answer by msny Wednesday, August 19, 2009 7:33 PM
    Wednesday, August 19, 2009 12:21 PM
  • Paul-

    Thank you for the code, I will give it a try and let you know.

    The second approach is more direct to what I need, cause I can pass in the
    Group name and just check that persons windows identity against that list.

    If there in the members list of that group, I let them into the form, else they get a message
    box. The form is called from an MDI menu.

    Again, thank you for taking the time to post!
    • Edited by msny Wednesday, August 19, 2009 4:39 PM
    Wednesday, August 19, 2009 4:37 PM
  • Public Sub ListADGroupMembers()
    
            ' local variables
            Dim DirectoryRoot As New DirectoryEntry("LDAP://RootDSE")
            Dim DNC = DirectoryRoot.Properties("DefaultNamingContext")(0).ToString()
            Dim UserIdentityName As System.Security.Principal.WindowsIdentity
    
            ' pass the group name for its members
            Dim GroupName As String = "HR-BG"
            Dim GroupMembers As System.Collections.Specialized.StringCollection = GetGroupMembers(DNC, GroupName)
    
            ' string fields for username 
            Dim StrName As String
            Dim StrLength As Integer
    
            ' logged in windows username
            UserIdentityName = System.Security.Principal.WindowsIdentity.GetCurrent()
    
            ' strip the Domain name including the \
            ' for just the user name
            StrName = UserIdentityName.Name.ToString
            StrLength = Len(StrName)
            StrLength = StrLength - 6
            StrName = StrName.Substring(6, StrLength)
    
            ' loop through the members looking for this user
            For Each Member As String In GroupMembers
    
                ' is the logged in windows member in this group?
                If Member.ToString = StrName.ToString Then
    
                    ' windows user in this AD group    
                    MsgBox(Member)
    
                    ' found, so end loop    
                    Exit For
    
                End If
    
            Next Member
    
        End Sub

    After a few modifications here is what I have now, works perfectly, returning in the msgbox

    the name of the user in the group specified.

    Thank you Paul!

     

     

    Wednesday, August 19, 2009 7:30 PM
  • Awesome, id done half of this myself before but never got it fully working.

    tagging the thread so i dont lose it :)
    Thursday, August 20, 2009 8:27 AM
  • Paul,
    where have you been for the past 2 months?? :-)
    I just wanted to say a big thank you.

    I had asked a very similar question last month where I was trying to retrieve all group information for a user.

    where user A was in group A, but group A was in Groups B and D so, User A was in groups A, B and D no one could help (with any real results)

    I have now modified your code, to do a recursive search and build a collection of groups and it works a treat.

    again many many thanks,

    and keep up the good work.


    regards Dogs_Bollox
    • Edited by dogs_bollox Thursday, August 20, 2009 11:51 AM formatting
    Thursday, August 20, 2009 11:49 AM
  • dogs_bollox,

    I remember seeing your question and I was working on something that didn't involved recursion, but got sidetracked by other priorities. I'll have to see if I can find the code now.
    Paul ~~~~ Microsoft MVP (Visual Basic)
    Thursday, August 20, 2009 12:03 PM