12
votes

TSQL: Comment obtenir une liste de groupes qu'un utilisateur appartient à Active Directory

J'ai deux questions qui récupèrent tous les groupes et tous les utilisateurs d'un domaine, MyDomain xxx

Ce que je voudrais savoir, c'est,
< / p>

Comment récupérez-vous une liste de tous les groupes dans Mydomain qu'un utilisateur particulier appartient à?

[Mise à jour ] j'ai pu obtenir le résultat opposé
Compte tenu du nom du groupe, récupérez tous les utilisateurs xxx


0 commentaires

5 Réponses :


-1
votes

Le centre de script Microsoft Tech Techet est une excellente ressource pour les scripts

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

Voici un script qui prétend donner exactement ce que vous voulez:

http: //gallery.technet .microsoft.com / ScriptCenter / en-US / AB5400E2-489A-4738-9B85-508BCB5B75F8


1 commentaires

@Raj: Merci pour ces liens. Je suis allé à travers beaucoup de scripts que j'ai pu le faire par programme, disons en C # ou PowerShell, mais je n'ai pas réussi à les traduire en ldap requêtes dans TSQL.



13
votes

Je pense que c'est l'une des limitations de l'interface AD ​​basée sur T-SQL - vous ne pouvez pas récupérer des attributs multi-valorisés, par ex. Attributs (comme membre de pour l'utilisateur) qui ont plus d'une valeur en eux.

Vous pouvez récupérer des attributs à valeur mono-value comme "sn" (nom de famille = nom) ou "nom donné" et "mail", etc., mais l'interface SQL n'est pas capable de manipuler des attributs tels que "Membre de" plusieurs valeurs qui leur sont attribuées.

Donc, j'ai bien peur que vous deviez aller un autre moyen pour ce problème - par exemple. Trouvez et remplissez l'appartenance au groupe dans le code géré (séparément en dehors du serveur SQL, ou éventuellement en tant qu'assemblage CLR à l'intérieur du serveur SQL).

Mise à jour: Voir ici (support MSDN) pour une explication de la limitation du fournisseur d'annonces OpenQuery:

Limitations
Le processus d'utilisation de la Déclaration d'openquery à tirer Les informations d'un serveur LDAP font souffrir de certaines limitations. Les Les limitations peuvent être contournées dans certains cas, mais dans d'autres la La conception des applications doit être modifiée. Un Application externe ou objet COM qui utilise ADSI pour récupérer le informations du serveur LDAP et Ensuite, construisez une table en SQL en utilisant ADO ou d'autres méthodes d'accès aux données sont une autre méthode viable.

La première limitation est que Les propriétés multiples ne peuvent pas être retourné dans le jeu de résultats à SQL Serveur. Adsia va lire le schéma informations du serveur LDAP qui Définit la structure et la syntaxe de les classes et attributs utilisés par le serveur. Si l'attribut qui est demandé à partir du serveur LDAP est défini dans le schéma comme étant Multi-valorisé, il ne peut pas être retourné dans une déclaration openquery.


4 commentaires

La raison pour laquelle j'ai été déterminée à découvrir à ce sujet était parce que j'ai pu faire exactement le nom du groupe, récupérer tous les utilisateurs appartenant au groupe. (Question mise à jour à cette fin)


Oui, car c'est une liste de toutes les entrées à valeur unique, essentiellement. Le "membre de" pour l'utilisateur est un attribut unique qui est multi-évalué et comporte plusieurs entrées (quelque chose de totalement contraire à 1NF en conception relationnelle)


Avec votre requête, vous récupérez une liste d'objets utilisateur dans AD - et pour chacun d'entre eux, vous n'ayez jamais accès à des attributs à valeur unique (CN, SN, ObjectCategory, etc.)


On dirait que je devrais changer la stratégie en créant une fonction de distinction, CLR et SproC. Merci, Marc_s.



16
votes

Vous pouvez y parvenir en récupérant tous les groupes contenant l'utilisateur dans leur attribut membre, ou mieux le chemin LDAP de l'utilisateur (distinguéeName). Voici une procédure simple qui fait ce travail.

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


0 commentaires

1
votes

En réalité, reportez-vous à la liste de tous les groupes auxquels un utilisateur appartient n'est pas aussi simple / facile qu'il semble. Pour autant que je ne connaisse ni PowerShell ni d'autres scripts ne peuvent fournir des résultats complètement précis, même lors de la récupération de l'attribut TokenGroups, car afin de faire cette détermination, il faut également envisager l'adhésion à des groupes de construction, qui sont spécifiques à un domaine.

Il y a un fil très utile sur ActiveDirSec.org que je pense que vous pourriez trouver utile - Comment énumérer la liste de tous les groupes de sécurité de domaine Active Directory qui appartient à un utilisateur?

Dans mon expérience, j'ai appris que ce n'est pas aussi facile qu'il y paraît, et à moins que vous ayez un moyen de vérifier la sortie à coup sûr, il n'est également aucun moyen de savoir si votre script fournit les bons résultats.


0 commentaires

21
votes

Procédure stockée ci-dessous, exécutez l'exemple:

get_adgroups_foruser strong> 'beau.holland' --Accountname P> blockQuote>

Remarque: Remplacez LDAP: // DC = Domain, DC = local avec votre propre domaine. P>

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


2 commentaires

C'est une bonne réponse et mérite plus de votes. Idéalement, vous pourriez obtenir la voie dans une sous-requête, mais cela fonctionne bien, peu importe.


@Elias - convenu. Ce suffixe de sous-arbre est si utile. Pour les autres intéressés, chez support2.microsoft.com/kb/187529 Vous trouverez plus d'informations à propos de définir ce type de chose.