【问题标题】:TSQL: How to get a list of groups that a user belongs to in Active DirectoryTSQL:如何在 Active Directory 中获取用户所属的组列表
【发布时间】:2009-11-19 19:50:32
【问题描述】:

我有两个查询来检索域中的所有组和所有用户,Mydomain

--; Get all groups in domain MyDomain
select  *  
from    OpenQuery(ADSI, '
    SELECT  samaccountname,mail,sn,name, cn, objectCategory
    FROM    ''LDAP://Mydomain/CN=users,DC=Mydomain,DC=com'' 
    WHERE   objectCategory=''group'' 
    ORDER BY cn
    ')

--; Get all users in domain MyDomain
select  *  
from    OpenQuery(ADSI,'
    SELECT objectCategory, cn, sn, mail, name, department,samaccountname
    FROM ''LDAP://Mydomaindomain/CN=users,DC=Mydomain,DC=com'' 
    WHERE objectCategory=''user'' 
    ORDER BY cn
    ')
--  where   samaccountname='mylogin'

我想知道的是,

如何检索MyDomain 中特定用户所属的所有组的列表?

[UPDATE] 我得到了相反的结果
给定组名,检索所有用户

select  *  
from    OpenQuery(ADSI,
    'SELECT objectCategory, cn, sn, mail, name, department
    FROM ''LDAP://Mydomain/CN=users,DC=wl-domain,DC=com'' 
    WHERE MemberOf=''cn=_____GROUPNAME_____,CN=users,DC=Mydomain,DC=com''
    ORDER BY cn' 
    )

【问题讨论】:

    标签: sql sql-server tsql active-directory


    【解决方案1】:

    下面的存储过程,用例子执行:

    Get_ADGroups_ForUser 'Beau.Holland' --AccountName

    注意:将 LDAP://DC=Domain,DC=local 替换为您自己的域。

    CREATE PROCEDURE dbo.Get_ADGroups_ForUser
    (
        @Username NVARCHAR(256) 
    )
    AS
    BEGIN
    
        DECLARE @Query NVARCHAR(1024), @Path NVARCHAR(1024)
    
        -- Find the fully qualified CN e.g: CN=Beau Holland,OU=Users,OU=Australia,OU=NSO,OU=Company,DC=Domain,DC=local
        -- replace "LDAP://DC=Domain,DC=local" with your own domain
        SET @Query = '
            SELECT @Path = distinguishedName
            FROM OPENQUERY(ADSI, ''
                SELECT distinguishedName 
                FROM ''''LDAP://DC=Domain,DC=local''''
                WHERE 
                    objectClass = ''''user'''' AND
                    sAMAccountName = ''''' + @Username + '''''
            '')
        '
        EXEC SP_EXECUTESQL @Query, N'@Path NVARCHAR(1024) OUTPUT', @Path = @Path OUTPUT 
    
        -- get all groups for a user
        -- replace "LDAP://DC=Domain,DC=local" with your own domain
        SET @Query = '
            SELECT cn,AdsPath
            FROM OPENQUERY (ADSI, ''<LDAP://DC=Domain,DC=local>;(&(objectClass=group)(member:1.2.840.113556.1.4.1941:=' + @Path +'));cn, adspath;subtree'')'
    
        EXEC SP_EXECUTESQL @Query  
    
    END
    GO
    

    【讨论】:

    • 这是一个很好的答案,值得更多的投票。理想情况下,您可以在子查询中获取路径,但这无论如何都很好。
    • @Elias - 同意。那个子树后缀非常有用。对于其他感兴趣的人,在support2.microsoft.com/kb/187529,您可以找到有关设置此类事情的更多信息。
    【解决方案2】:

    您可以通过获取在其成员属性中包含用户的所有组,或者更好地获取用户的 LDAP 路径(distinguishedName)来实现此目的。这是完成这项工作的简单程序。

    
    CREATE PROCEDURE dbo.GetLdapUserGroups
    (
        @LdapUsername NVARCHAR(256)
    )
    AS
    BEGIN
        DECLARE @Query NVARCHAR(1024), @Path NVARCHAR(1024)
    
        SET @Query = '
            SELECT @Path = distinguishedName
            FROM OPENQUERY(ADSI, ''
                SELECT distinguishedName 
                FROM ''''LDAP://DC=domain,DC=com''''
                WHERE 
                    objectClass = ''''user'''' AND
                    sAMAccountName = ''''' + @LdapUsername + '''''
            '')
        '
        EXEC SP_EXECUTESQL @Query, N'@Path NVARCHAR(1024) OUTPUT', @Path = @Path OUTPUT 
    
        SET @Query = '
            SELECT name AS LdapGroup 
            FROM OPENQUERY(ADSI,''
                SELECT name 
                FROM ''''LDAP://DC=domain,DC=com''''
                WHERE 
                    objectClass=''''group'''' AND
                    member=''''' + @Path + '''''
            '')
            ORDER BY name
        '
        EXEC SP_EXECUTESQL @Query
    
    END
    

    -- 希尔伯特

    【讨论】:

      【解决方案3】:

      我认为这是基于 T-SQL 的 AD 接口的限制之一 - 您无法检索多值属性,例如具有多个值的属性(例如用户的memberOf)。

      您可以检索“sn”(姓氏 = 姓氏)或“givenName”和“mail”等单值属性,但基于 SQL 的接口无法处理“memberOf”等属性分配给它们的几个值。

      所以恐怕你将不得不采取另一种方式来解决这个问题 - 例如。在托管代码中查找和填充组成员身份(单独在 SQL Server 之外,或者可能作为 SQL Server 内部的 CLR 程序集)。

      更新:请参阅here (MSDN Support),了解 OPENQUERY AD 提供程序的限制:

      限制
      使用过程 OPENQUERY 语句拉取 来自 LDAP 服务器的信息 受到一些限制。这 可以绕过限制 在某些情况下,但在其他情况下 必须更改应用程序设计。一个 外部应用程序或 COM 对象 使用 ADSI 检索 来自 LDAP 服务器的信息和 然后使用 ADO 在 SQL 中构建一个表 或其他数据访问方法是 另一种可行的方法。

      第一个限制是那个 多值属性不能 在结果集中返回给 SQL 服务器。 ADSI 将读​​取架构 来自 LDAP 服务器的信息 定义结构和语法 使用的类和属性 服务器。如果属性是 从 LDAP 服务器请求的是 在模式中定义为 多值它不能返回 OPENQUERY 语句。

      【讨论】:

      • 我之所以下定决心要找出这件事,是因为,我能够做完全相反的事情——给定组名,检索属于该组的所有用户。 (为此目的更新了问题)
      • 是的,因为基本上这是所有单值条目的列表。用户的“memberOf”是一个多值且有多个条目的单一属性(这与关系设计中的 1NF 完全相反)
      • 通过您的查询,您将返回 AD 中的用户对象列表 - 对于每个用户对象,您只能访问和使用单值属性(cn、sn、objectCategory 等)。 )
      • 看来我必须通过创建一个 CLR 函数/存储过程来改变策略。谢谢,marc_s。
      【解决方案4】:

      实际上,检索用户所属的所有组的列表并不像看起来那么简单/容易。据我所知,PowerShell 和其他脚本都无法提供完全准确的结果,即使在检索 tokenGroups 属性时也是如此,因为为了进行此确定,还必须考虑特定领域的内置组的成员资格。

      ActiveDirSec.org 上有一个非常有用的帖子,我认为您可能会发现它很有用 - How to enumerate the list of all Active Directory domain security groups that a user belongs to?

      根据我的经验,我了解到这并不像看起来那么容易,除非您有办法确定验证输出,否则也无法知道您的脚本是否提供了正确的结果。

      【讨论】:

        【解决方案5】:

        Microsoft Technet 脚本中心是一个很好的脚本资源

        http://technet.microsoft.com/en-us/scriptcenter/default.aspx

        这是一个声称能准确给出你想要的东西的脚本:

        http://gallery.technet.microsoft.com/ScriptCenter/en-us/ab5400e2-489a-4738-9b85-508bcb5b75f8

        【讨论】:

        • @Raj:感谢您提供这些链接。我已经浏览了许多脚本,我能够以编程方式完成它,比如在 C# 或 powershell 中,但我未能将它们转换为 TSQL 中的LDAP 查询。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多