4

我正在尝试通过以下两种方式之一找到查询 Active Directory 的最简单方法:

  1. 给定一个 AD 用户名,找到该用户所属的所有组(包括嵌套组)。

  2. 给定一个 AD 组名称,查找属于该组的所有用户(包括嵌套组中的用户)。

我的应用程序位于 v4.0 框架上的 VB.NET 中。我查看了来自许多不同 Google 搜索结果的建议,其中一些使用了 LDAP 和 System.DirectoryServices.DirectorySearcher(我认为这可能是最好的途径)。

但我正在转动我的轮子并正在寻找代码示例。

谢谢你。

更新:

我已经准备好这些部分:

<add assembly="System.DirectoryServices, Version=3.5.0.0, etc."/>

<add namespace="System.DirectoryServices.AccountManagement" />或者Imports System.DirectoryServices.AccountManagement

在这行代码上:

Dim ctx As New PrincipalContext(ContextType.Domain)

我仍然收到此错误: 未定义类型“PrincipalContext”

当您提到“using 语句”时,我假设您的意思是我需要引用此命名空间。或者你的意思是我应该做这样的事情?

Using ctx As New PrincipalContext(ContextType.Domain)

4

3 回答 3

4

一个完整的例子

此代码将通过枚举给定的组名称列出组和子组中的所有用户。此外,如果启用/禁用用户帐户。

要使用,只需调用 ListADGroupMembers("Some_Group_Name")。这会将用户的全名和手机号码填充到一个数组中,然后您可以循环访问该数组。

它非常简单,只需通读一遍。

Public ADUSers(,) As String
 Public n As Integer = 0

 Public Sub ListADGroupMembers(ByVal GN As String)

    Dim DirectoryRoot As New DirectoryEntry("LDAP://RootDSE")
    Dim DNC = DirectoryRoot.Properties("DefaultNamingContext")(0).ToString()
    Dim GroupName As String = GN '"G_All_IT_Users"
    Dim GroupMembers As System.Collections.Specialized.StringCollection = GetGroupMembers(DNC, GroupName)
    'Dim GroupMembersMobile As System.Collections.Specialized.StringCollection = GetGroupMembers(DNC, GroupName)
    '  For Each Member As String In GroupMembers
    '    ListBox1.Items.Add(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
                Dim DirectoryPhone As Object = DirectoryMemberProperties("mobile").Value
                Dim uac As Object = DirectoryMemberProperties("userAccountControl").Value

                If DirectoryMember.SchemaClassName = "group" Then
                    ' this is a group.                        
                    ListADGroupMembers(DirectoryItem)
                End If

                If DirectoryMember.SchemaClassName = "user" Then
                    ' this is a user.
                    If Nothing IsNot DirectoryItem Then
                        If AccEnabled(uac) = 1 Then ' check the ad account is enabled
                            GroupMembers.Add(DirectoryItem.ToString())
                            ListBox1.Items.Add(DirectoryItem.ToString() & " " & DirectoryPhone)

                            ADUSers(0, n) = DirectoryItem.ToString()
                            ADUSers(1, n) = DirectoryPhone
                            n += 1
                            ReDim Preserve ADUSers(1, n)
                        End If
                    End If
                End If

            Next GroupMemberDN

        Next DirectorySearchResult
    Catch ex As Exception
        MsgBox(ex.Message)
    End Try

    Return GroupMembers



End Function




  ' check account is active or not.
Function AccEnabled(ByVal uac As String) As String

    Dim aret As Integer = 0
    Select Case uac
        Case 512 'Enabled 
            aret = 1
        Case 514 ': ACCOUNTDISABLE()
            aret = 0
        Case 528 ': Enabled(-LOCKOUT)
            aret = 1
        Case 530 ': ACCOUNTDISABLE(-LOCKOUT)
            aret = 0
        Case 544 ': Enabled(-PASSWD_NOTREQD)
            aret = 1
        Case 546 ': ACCOUNTDISABLE(-PASSWD_NOTREQD)
            aret = 0
        Case 560 ': Enabled(-PASSWD_NOTREQD - LOCKOUT)
            aret = 1
        Case 640 ': Enabled(-ENCRYPTED_TEXT_PWD_ALLOWED)
            aret = 1
        Case 2048 ' : INTERDOMAIN_TRUST_ACCOUNT()
            aret = 1
        Case 2080 ': INTERDOMAIN_TRUST_ACCOUNT(-PASSWD_NOTREQD)
            aret = 1
        Case 4096 ': WORKSTATION_TRUST_ACCOUNT()
            aret = 1
        Case 8192 ': SERVER_TRUST_ACCOUNT()
            aret = 1
        Case 66048 ': Enabled(-DONT_EXPIRE_PASSWORD)
            aret = 1
        Case 66050 ': ACCOUNTDISABLE(-DONT_EXPIRE_PASSWORD)
            aret = 0
        Case 66064 ': Enabled(-DONT_EXPIRE_PASSWORD - LOCKOUT)
            aret = 1
        Case 66066 ': ACCOUNTDISABLE(-DONT_EXPIRE_PASSWORD - LOCKOUT)
            aret = 0
        Case 66080 ': Enabled(-DONT_EXPIRE_PASSWORD - PASSWD_NOTREQD)
            aret = 1
        Case 66082 ': ACCOUNTDISABLE(-DONT_EXPIRE_PASSWORD - PASSWD_NOTREQD)
            aret = 0
        Case 66176 ': Enabled(-DONT_EXPIRE_PASSWORD - ENCRYPTED_TEXT_PWD_ALLOWED)
            aret = 1
        Case 131584 ': Enabled(-MNS_LOGON_ACCOUNT)
            aret = 1
        Case 131586 ': ACCOUNTDISABLE(-MNS_LOGON_ACCOUNT)
            aret = 0
        Case 131600 ': Enabled(-MNS_LOGON_ACCOUNT - LOCKOUT)
            aret = 1
        Case 197120 ': Enabled(-MNS_LOGON_ACCOUNT - DONT_EXPIRE_PASSWORD)
            aret = 1
        Case 532480 'SERVER_TRUST_ACCOUNT - TRUSTED_FOR_DELEGATION (Domain Controller) 
            aret = 1
        Case 1049088 ': Enabled(-NOT_DELEGATED)
            aret = 1
        Case 1049090 ': ACCOUNTDISABLE(-NOT_DELEGATED)
            aret = 0
        Case 2097664 ': Enabled(-USE_DES_KEY_ONLY)
            aret = 1
        Case 2687488 ': Enabled(-DONT_EXPIRE_PASSWORD - TRUSTED_FOR_DELEGATION - USE_DES_KEY_ONLY)
            aret = 1
        Case 4194816 ': Enabled(-DONT_REQ_PREAUTH)
            aret = 1
        Case Else
            aret = 0
    End Select

    AccEnabled = aret

End Function
于 2012-12-17T10:14:58.283 回答
3

试试这个:

' set up domain context
Dim ctx As New PrincipalContext(ContextType.Domain)

' find a user
Dim user As UserPrincipal = UserPrincipal.FindByIdentity(ctx, "SomeUserName")

If user IsNot Nothing Then
    Dim groupMemberships = user.GetAuthorizationGroups()

            ' do something with group....
    For Each gp As GroupPrincipal In groupMemberships
    Next
End If

您应该检查System.DirectoryServices.AccountManagement(S.DS.AM) 命名空间。在这里阅读所有相关信息:

新的 S.DS.AM 使得在 AD 中与用户和组一起玩变得非常容易!

该方法.GetAuthorizationGroups()将进行递归搜索-因此您应该直接或间接获取用户所属的所有组。

于 2012-10-25T04:55:47.597 回答
0
Imports System.Security.Principal

Private Function GetGroups(userName As String) As List(Of String)
    Dim result As New List(Of String)
    Dim wi As WindowsIdentity = New WindowsIdentity(userName)

    For Each group As IdentityReference In wi.Groups
        Try
            result.Add(group.Translate(GetType(NTAccount)).ToString())
        Catch ex As Exception
        End Try
    Next

    result.Sort()
    Return result
End Function

所以只需使用 GetGroups("userID")。因为这种方法使用用户的 SID,所以没有进行显式 LDAP 调用。如果您使用自己的用户名,它将使用缓存的凭据,因此此功能非常快。

Try Catch 是必要的,因为在大型公司中,AD 是如此之大,以至于一些 SID 在太空中迷失了方向。

https://stackoverflow.com/a/19403297/2886367

于 2013-10-16T13:34:07.073 回答