TSQL: como obter uma lista de grupos a que um utilizador pertence na pasta activa

tenho duas consultas que recuperam todos os grupos e todos os utilizadores num domínio, 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'
O que eu gostaria de descobrir é ... ,

Como você obtém uma lista de todos os grupos em MyDomain a que um usuário em particular pertence?

[UPDATE] consegui o resultado oposto
Dado o nome do Grupo, obter todos os utilizadores

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' 
    )
Author: Cœur, 2009-11-19

5 answers

Eu acho que esta é uma das limitações da interface AD baseada em T-SQL - você não pode obter atributos multi-valorizados, por exemplo atributos (como memberOf para o usuário) que têm mais de um valor neles.

Você pode obter atributos de valor único como" sn "(sobrenome = sobrenome) ou" givenName "e" mail "e assim por diante, mas a interface baseada em SQL não é capaz de lidar com atributos como" memberOf " com vários valores atribuídos a eles.

Por isso, receio que tenhas de ir. outra maneira para este problema - por exemplo, encontrar e preencher os membros do grupo em código gerenciado (separadamente fora do servidor SQL, ou possivelmente como um conjunto CLR dentro do servidor SQL).

Actualizar: Ver aqui (suporte MSDN) para uma explicação da limitação do Fornecedor de AD OPENQUERY:

Limitações
o processo de Utilização do Declaração do OPENQUERY a puxar a informação de um servidor LDAP faz sofre de algumas limitações. O as limitações podem ser contornado em em alguns casos, mas noutros o o desenho da aplicação deve ser alterado. Um aplicação externa ou objecto COM que usa ADSI para recuperar o informações do servidor LDAP e em seguida, construir uma tabela em SQL usando ADO ou outros métodos de acesso a dados é outro método viável.

A primeira limitação é que as propriedades multivaladas não podem ser devolvido no conjunto de resultados para SQL Servidor. ADSI irá ler o esquema informação de o servidor LDAP que define a estrutura e sintaxe do as classes e atributos utilizados pelo servidor. Se o atributo que é é pedido ao servidor LDAP definido no esquema como sendo multi-valor não pode ser devolvido em uma declaração de abertura.

 10
Author: marc_s, 2009-11-19 20:36:21

Procedimento Armazenado em baixo, executar por exemplo:

Get_ADGroups_ForUser ' Beau.Holland ' -- AccountName

Nota: substitua LDAP://DC=domínio,DC=local pelo seu próprio domínio.

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
 15
Author: Beau, 2013-11-19 09:09:36

Você pode conseguir isso, obtendo todos os grupos que contêm o usuário em seu atributo membro, ou melhor o caminho LDAP do Usuário (distinguishedName). Eis um procedimento simples a fazer esse trabalho.


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

 12
Author: Hilbert Blank, 2010-07-07 18:02:39

Na verdade, arquivar a lista de todos os grupos a que um utilizador pertence não é tão simples / simples como parece. Tanto quanto eu sei, nem PowerShell nem outros scripts podem fornecer resultados completamente precisos, mesmo quando recuperando o atributo tokenGroups, porque, a fim de fazer esta dissuasão, um também tem que considerar a adesão em grupos Builtin, que são específicos de domínio.

Há um tópico muito útil sobre ActiveDirSec.org que eu acho que você pode achar útil - como enumerar a lista de todos os grupos activos de segurança do domínio de pastas a que um utilizador pertence?

Na minha experiência, aprendi que isto não é tão fácil como parece, e a menos que você tenha uma maneira de verificar a saída com certeza, não há também nenhuma maneira de saber se seu script está entregando os resultados certos.

 1
Author: Geoffrey Dawson, 2012-07-03 22:32:22

O Microsoft Technet Script Center é um grande recurso para scripts

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

Aqui está um script que diz dar exatamente o que você quer:

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

 -1
Author: Raj More, 2009-11-19 20:16:37