TSQL: How to get a list of groups that a user belongs to in Active Directory

后端 未结 5 1919
盖世英雄少女心
盖世英雄少女心 2020-12-16 01:47

I have two queries that retrieve all groups and all users in a domain, Mydomain

--; Get all groups in domain MyDomain
select  *  
from    OpenQu         


        
相关标签:
5条回答
  • 2020-12-16 02:10

    Actually, retreiving the list of all groups to which a user belongs is not as straight-forward / easy as it seems. As far as I know neither PowerShell nor other scripts can deliver completely accurate results, even when retrieving the tokenGroups attribute, because in order to make this determiantion, one also has to consider membership in Builtin Groups, which are domain specific.

    There is a very useful thread on ActiveDirSec.org that I think you might find useful - How to enumerate the list of all Active Directory domain security groups that a user belongs to?

    In my experience, I have learnt that this isn't as easy as it seems, and unless you have a way to verify the output for sure, there is also no way to know if your script is delivering the right results.

    0 讨论(0)
  • 2020-12-16 02:14

    The Microsoft Technet Script Center is a great resource for scripts

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

    Here is a script that claims to give out exactly what you want:

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

    0 讨论(0)
  • 2020-12-16 02:25

    Stored procedure below, execute using example:

    Get_ADGroups_ForUser 'Beau.Holland' --AccountName

    Note: replace LDAP://DC=Domain,DC=local with your own domain.

    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
    
    0 讨论(0)
  • 2020-12-16 02:27

    You can achieve this by fetching all groups that contain the user in their member attribute, or better the user's LDAP path (distinguishedName). Here's a simple procedure doing that job.

    
    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
    

    -- Hilbert

    0 讨论(0)
  • 2020-12-16 02:28

    I think this is one of the limitations of the T-SQL based AD interface - you cannot retrieve multi-valued attributes, e.g. attributes (like memberOf for the user) that have more than one value in them.

    You can retrieve single-valued attributes like "sn" (surname = last name) or "givenName" and "mail" and so forth, but the SQL-based interface isn't capable of handling attributes like "memberOf" with several values assigned to them.

    So I'm afraid you'll have to go another way for this problem - e.g. find and populate the group membership in managed code (separately outside of SQL Server, or possibly as a CLR assembly inside SQL Server).

    UPDATE: see here (MSDN Support) for an explanation of limitation of the OPENQUERY AD provider:

    Limitations
    The process of using the OPENQUERY statement to pull information from an LDAP server does suffer from some limitations. The limitations can be circumvented in some cases, but in others the application design must be altered. An external application or COM object that uses ADSI to retrieve the information from the LDAP server and then build a table in SQL by using ADO or other data access methods is another viable method.

    The first limitation is that multivalued properties cannot be returned in the result set to SQL Server. ADSI will read schema information from the LDAP server that defines the structure and syntax of the classes and attributes used by the server. If the attribute that is requested from the LDAP server is defined in the schema as being multi-valued it cannot be returned in an OPENQUERY statement.

    0 讨论(0)
提交回复
热议问题