web-dev-qa-db-ja.com

TSQL:Active Directoryでユーザーが属するグループのリストを取得する方法

ドメイン内のすべてのグループとすべてのユーザーを取得する2つのクエリ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' 
    )
11
dance2die

これは、T-SQLベースのADインターフェイスの制限の1つだと思います。たとえば、多値属性を取得できません。複数の値を持つ属性(ユーザーのmemberOfなど)。

「sn」(姓=姓)や「givenName」、「mail」などの単一値属性を取得できますが、SQLベースのインターフェースでは、複数の値が割り当てられた「memberOf」などの属性を処理できません彼らへ。

だから私はあなたがこの問題のために別の方法をしなければならないでしょう-例えばマネージコードでグループメンバーシップを検索して入力します(個別にSQL Serverの外部、またはSQL Server内のCLRアセンブリとして).

UPDATE:OPENQUERY ADプロバイダーの制限の説明については、 ここ(MSDNサポート) を参照してください:

制限事項
OPENQUERYステートメントを使用してLDAPサーバーから情報をプルするプロセスには、いくつかの制限があります。この制限を回避できる場合もありますが、アプリケーションの設計を変更する必要がある場合もあります。 ADSIを使用してLDAPサーバーから情報を取得し、ADOまたはその他のデータアクセスメソッドを使用してSQLでテーブルを作成する外部アプリケーションまたはCOMオブジェクトは、もう1つの実行可能なメソッドです。

最初の制限はである複数の値を持つプロパティはできない結果セットでSQL Serverに返されます。 ADSIは、サーバーによって使用されるクラスと属性の構造と構文を定義するスキーマ情報をLDAPサーバーから読み取ります。 LDAPサーバーから要求された属性が複数値を持つものとしてスキーマで定義されている場合、OPENQUERYステートメントで返すことはできません。

13
marc_s

以下のストアドプロシージャ、例を使用して実行:

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
22
Beau

これを行うには、メンバー属性にユーザーを含むすべてのグループをフェッチするか、ユーザーの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

-ヒルベルト

15
Hilbert Blank

実際、ユーザーが属するすべてのグループのリストを取得することは、見かけほど簡単ではありません。私が知る限り、tokenGroups属性を取得する場合でも、PowerShellも他のスクリプトも完全に正確な結果を提供することはできません。これは、この決定を行うために、ドメイン固有のビルトイングループのメンバーシップも考慮する必要があるためです。

ActiveDirSec.orgには非常に便利なスレッドがあり、役に立つと思うかもしれません- ユーザーが属するすべてのActive Directoryドメインセキュリティグループのリストを列挙する方法は?

私の経験では、これは思ったほど簡単ではないことを学びました。出力を確実に確認する方法がない限り、スクリプトが正しい結果を提供しているかどうかを知る方法もありません。

1
Geoffrey Dawson