如何获得AD用户的间接组? - C#

时间:2010-12-20 15:20:57

标签: c# .net active-directory directoryservices

我正在使用DirectorySearcher来获取他是使用'memberof'属性的成员的AD用户组。但根据this msdn page,'memberof'属性仅返回用户所属的直接组。我怎样才能得到用户的间接组。

对于前。

Group A -> User X, User Y, Group B
Group B -> User Z
Group C -> User Z

我希望将结果作为用户Z的A组,B组,C组,因为他是A组的间接用户。

更新

Okie。我已经按照this代码项目文章来递归地获取组。但是列表中仍然缺少内置组“域用户”。这是否意味着内置组不会出现在目录搜索器中?

4 个答案:

答案 0 :(得分:1)

您必须定义自己的迭代直接组的方法,直到达到所有的公共根。您需要对每个组执行LDAP查询,并使用相同的memberOf属性来确定该组所属的组。这可能是时间密集的,特别是如果这些群体很多并且布局像网络一样。

答案 1 :(得分:1)

我的答案遵循与Joel Etherton相同的方式,但有代码。我刚刚在我的一个应用程序中实现了这一点。您需要做的就是将VB.Net解释为C#:)。下面的代码将采用一个组并返回所有子组。所以你只需要遍历每个组并将它们放在一个列表中。我引用了一些我没有包含的方法,但应该是自我解释的。我确实包含了PrincipalGenericCollection,因为它可以很方便。

Public Function GetSubGroups(ByVal groupname As String) As List(Of String)
    Dim result As New List(Of String)()

    GetSubGroups(groupname, result)

    Return result
End Function

Public Sub GetSubGroups(ByVal Group As String, ByRef l As List(Of String))
    Dim grp = GetGroup(Group)

    'sometimes group will be null if its a system built in group like "authenticated users"'
    If grp Is Nothing Then
        Exit Sub
    End If

    Dim sGroups = GetGroupMembership(Group, False).Where(Function(c) TypeOf c Is GroupPrincipal)

    For Each g In sGroups
        Dim n As String = FormatPrincipalName(g.Name)

        If Not l.Contains(n) Then
            l.Add(n)

            GetSubGroups(g.Name, l)
        End If
    Next
End Sub

Public Function GetGroupMembership(ByVal GroupName As String, Optional ByVal Recursive As Boolean = True) As PrincipalGenericCollection(Of Principal)
    Dim group As GroupPrincipal = GetGroup(GroupName)

    If group Is Nothing Then
        Return Nothing
    End If

    Dim prinCol As New PrincipalGenericCollection(Of Principal)(group.GetMembers(Recursive))

    prinCol.SortByName()

    Return prinCol
End Function


Public Class PrincipalGenericCollection(Of T As Principal)
    Inherits List(Of T)

    Public Sub New()
        MyBase.New()
    End Sub

    Public Sub New(ByVal collection As PrincipalCollection)
        For Each p As Principal In collection
            Me.Add(p)
        Next
    End Sub

    Public Sub New(ByVal collection As IEnumerable(Of T))
        MyBase.New(collection)
    End Sub

    Public Sub SortByName()
        Sort(New PrincipalSorter(Of T))
    End Sub
End Class

答案 2 :(得分:1)

用户的主要组不会显示在“memberOf”属性中。 相反,它的RID存储在“primaryGroupID”属性中,您必须从该RID(域SID +组RID)计算组的SID。

这就是为什么你找不到Domain Users组(这是用户的主要组)

答案 3 :(得分:0)

听起来像一个简单的递归方法。查找组,用户是每个组的成员,查找组,组是其成员。重复,直到找不到更多成员资格。