2009-11-19 6 views
7

Tôi có hai câu hỏi mà lấy tất cả các nhóm và tất cả người dùng trong một miền, MydomainTSQL: Làm thế nào để có được một danh sách các nhóm mà người dùng thuộc về trong Active Directory

--; 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' 

Những gì tôi muốn tìm hiểu is,

Làm cách nào để bạn truy xuất danh sách tất cả các nhóm trong MyDomain mà một người dùng cụ thể thuộc về?

[UPDATE] tôi đã có thể để có được kết quả ngược lại
Với tên nhóm, lấy tất cả người dùng

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' 
    ) 

Trả lời

10

Tôi nghĩ rằng đây là một trong những hạn chế của giao diện AD T-SQL dựa - bạn không thể lấy thuộc tính đa giá trị, ví dụ các thuộc tính (như memberOf cho người dùng) có nhiều giá trị trong đó.

Bạn có thể truy xuất các thuộc tính đơn giá trị như "sn" (họ hoặc tên) và "tên" và "vv", nhưng giao diện dựa trên SQL không có khả năng xử lý các thuộc tính như "memberOf" với một vài giá trị được gán cho chúng.

Vì vậy, tôi e rằng bạn sẽ phải đi theo một cách khác cho vấn đề này - ví dụ: tìm và cư trú thành viên nhóm trong mã được quản lý (riêng bên ngoài SQL Server, hoặc có thể là một hội đồng CLR bên trong SQL Server).

UPDATE: thấy here (MSDN Support) cho một lời giải thích của giới hạn của nhà cung cấp OPENQUERY AD:

Hạn chế
Quá trình sử dụng câu lệnh OPENQUERY để kéo thông tin từ một máy chủ LDAP không bị số hạn chế. Các giới hạn có thể bị phá vỡ trong một số trường hợp, nhưng trong các trường hợp khác, thiết kế ứng dụng phải được thay đổi. An ứng dụng bên ngoài hoặc đối tượng COM sử dụng ADSI để truy xuất thông tin từ máy chủ LDAP và sau đó tạo bảng trong SQL bằng cách sử dụng ADO hoặc phương pháp truy cập dữ liệu khác là .

Hạn chế đầu tiên là rằng tính đa giá trị không thể trả lại trong kết quả thiết to SQL Server.ADSI sẽ đọc lược đồ thông tin từ máy chủ LDAP xác định cấu trúc và cú pháp của các lớp và thuộc tính được sử dụng bởi máy chủ . Nếu thuộc tính được yêu cầu từ máy chủ LDAP là được xác định trong giản đồ dưới dạng nhiều giá trị, thì không thể trả lại trong câu hỏi OP2QUERY .

+0

Lý do tôi quyết tâm tìm hiểu về điều này là bởi vì, tôi đã có thể làm ngược lại với tên nhóm, lấy tất cả người dùng thuộc về nhóm. (Câu hỏi được cập nhật cho mục đích này) – Sung

+0

có, bởi vì đó là một danh sách tất cả các mục có giá trị duy nhất, về cơ bản. "MemberOf" cho người dùng là một thuộc tính duy nhất có nhiều giá trị và có nhiều mục (hoàn toàn trái ngược với 1NF trong thiết kế quan hệ) –

+0

với truy vấn của bạn, bạn lấy lại danh sách đối tượng người dùng trong AD - và cho từng đối tượng của họ, bạn chỉ bao giờ truy cập và sử dụng các thuộc tính có giá trị đơn (cn, sn, objectCategory, v.v.) –

-1

Các Microsoft Technet Script Center là một nguồn lực lớn cho các kịch bản

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

Đây là tập lệnh xác nhận quyền sở hữu để đưa ra chính xác những gì bạn muốn:

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

+3

không chính xác là T-SQL, tuy nhiên ..... –

+0

@Raj: Cảm ơn bạn đã liên kết. Tôi đã đi qua nhiều kịch bản tôi đã có thể làm điều đó lập trình, nói trong C# hoặc powershell nhưng tôi đã không dịch chúng thành các truy vấn 'LDAP' trong TSQL. – Sung

12

Bạn có thể đạt được điều này bằng cách tìm nạp tất cả các nhóm chứa người dùng trong thuộc tính thành viên của họ hoặc tốt hơn đường dẫn LDAP của người dùng (tên phân biệt). Đây là một thủ tục đơn giản thực hiện công việc đó.


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

1

Trên thực tế, retreiving danh sách của tất cả các nhóm mà người dùng thuộc không phải là thẳng về phía trước/dễ dàng như nó có vẻ. Theo như tôi biết không PowerShell hay các kịch bản khác có thể cung cấp kết quả chính xác hoàn toàn, ngay cả khi truy xuất thuộc tính tokenGroups, vì để đưa ra quyết định này, người ta cũng phải xem xét thành viên trong nhóm Builtin, tên miền cụ thể.

Có một chủ đề rất hữu ích trên ActiveDirSec.org mà tôi nghĩ rằng bạn có thể thấy hữu ích - How to enumerate the list of all Active Directory domain security groups that a user belongs to?

Theo kinh nghiệm của tôi, tôi đã học được rằng đây không phải là dễ dàng như nó có vẻ, và trừ khi bạn có một cách xác minh đầu ra chắc chắn, cũng không có cách nào để biết liệu tập lệnh của bạn có đang cung cấp kết quả đúng hay không.

15

Thủ tục lưu trữ bên dưới, thực hiện sử dụng ví dụ:

Get_ADGroups_ForUser 'Beau.Holland' --AccountName

Lưu ý: thay thế LDAP: // DC = Domain, DC = local với tên miền của riêng bạn.

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

Đây là một câu trả lời tuyệt vời và xứng đáng được nhiều phiếu bầu hơn. Lý tưởng nhất là bạn có thể nhận được đường dẫn trong truy vấn phụ, nhưng điều này hoạt động tốt bất kể. – Elias

+1

@Elias - đã đồng ý. Hậu tố subtree đó rất hữu ích. Đối với những người khác quan tâm, tại http://support2.microsoft.com/kb/187529 bạn sẽ tìm thấy thêm thông tin về cách thiết lập loại điều này. –