在 SQL 中确定 Active Directory 组和成员的最简单方法

Posted

技术标签:

【中文标题】在 SQL 中确定 Active Directory 组和成员的最简单方法【英文标题】:Easiest Method for determining Active Directory groups and members in SQL 【发布时间】:2016-07-01 17:35:09 【问题描述】:

我需要在 s-s-rS (T-SQL) 中编写一个报告,显示任何当前用户在他们具有读取访问权限的 s-s-rS 报告服务器上进行报告,目前由 Active Directory 确定。更复杂的是,Active Directory 没有将组设置为组元素 - AD 中的所有用户都是 objectClass=User 和 objectCategory=Person。

我的问题是:如何编写一个查询,将用户与其所有“memberOf”元素匹配,而不必知道组名是什么(因为它们可能会改变等)?从那里,我想我可以拼凑出如何将每个元素与报告相匹配。

编辑:这是我到目前为止所写的。由于语法错误,它没有创建过程,但我无法发现错误。

USE [ReportServer]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [dbo].[ActiveDirectoryPermissions]
AS 
BEGIN
SET NOCOUNT ON;
DECLARE @Table1 TABLE
(
    [GroupName] nvarchar(MAX),
    [GroupPath] nvarchar(MAX)
)

INSERT INTO @Table1 ( [GroupName], [GroupPath] )
    SELECT sAMAccountName as [GroupName], replace(ADsPath,'LDAP://','') as [GroupPath]
        FROM OPENQUERY( ADSI,
        'SELECT sAMAccountname, ADsPath
        FROM ''LDAP://DC=[REDACTED],DC=COM''
        WHERE objectCategory=''group'' AND CN=''*''
        ORDER BY CN')

DECLARE @Table2 TABLE
(
    [GroupPath] nvarchar(MAX),
    [MemberName] nvarchar(MAX)
)

DECLARE table_1_cursor CURSOR FOR
    SELECT GroupPath
    FROM @Table1 t1

DECLARE @SQL nvarchar(MAX)
DECLARE @temp nvarchar(MAX)

OPEN table_1_cursor
FETCH NEXT FROM table_1_cursor INTO @temp

WHILE @@FETCH_STATUS = 0
BEGIN
    SET @SQL = 'SELECT '''+@temp+''' AS GroupPath, cn 
        FROM OPENQUERY(ADSI,
        ''SELECT cn 
        FROM ''''LDAP://DC=[REDACTED],DC=com''''
        WHERE
        memberOf='''''+@temp+'''''
        '')'
    INSERT INTO @Table2 ( [GroupPath], [MemberName] )
        EXEC sp_executesql @SQL;

    FETCH NEXT FROM table_1_cursor INTO @temp
END

CLOSE table_1_cursor
DEALLOCATE table_1_cursor

SELECT *
FROM @Table2 t2
INNER JOIN @Table1 t1 ON (t2.GroupPath=t1.GroupPath)

GO

【问题讨论】:

我已经添加了当前因为语法错误而拒绝编译的代码,但是我找不到错误。 Msg 102, Level 15 ,State 1, Procedure ActiveDirectoryPermissions, Line 56 [Batch Start Line 8] ')' 附近的语法不正确。 是的。在我读到这篇文章之前抓住了丢失的“END”。 derp 而ADSI就是暴露AD的链接服务器,是的。现在应该可以了。谢谢你的帮助,迈克! 【参考方案1】:

注释掉存储过程的内容并创建它。然后通过一次一个取消注释语句来更改存储过程。您也可以尝试注释掉部分 select 语句。我怀疑问题出在你在哪里构建@ sql。此时我会选择@temp 和@sql。直接运行代码,而不是作为过程的一部分。这样您就可以手动检查和测试输出。坚持到这一步做得很好。那些 ' 会让我发疯的。

您缺少存储过程的最后一个 END。下一个问题:什么是 ADSI?我认为这是公开 AD 的链接服务器的名称?如

https://www.mssqltips.com/sqlservertip/2580/querying-active-directory-data-from-sql-server/

还有一种不需要链​​接服务器的访问 AD 的替代方法。

EXEC master.dbo.sp_QueryAD   
    'SELECT sAMAccountname, ADsPath
    FROM ''LDAP://OU=REDACTED,DC=REDACTED''
    WHERE objectCategory=''group'' AND CN=''*''
    ORDER BY CN'

有少量配置可以启用此功能,但如果您搜索错误,只需一点时间即可设置。

【讨论】:

以上是关于在 SQL 中确定 Active Directory 组和成员的最简单方法的主要内容,如果未能解决你的问题,请参考以下文章

Azure SQL Active Directory集成身份验证,联合域

使用 SQL Server 2005 通过 LDAP 访问 Active Directory 角色成员资格

SCCM TP4部署前的Active Directory准备

Swift:在调用 applicationDidEnterBackground 时确定 Active View Controller

SQL Server - 如何确定select查询中条件的优先级

如何在 SQL Server 中添加 Active Directory 用户组作为登录名