在我所做的所有的阅读和研究之后,这似乎是发表这个问题最合乎逻辑的地方:
为什么我可以使用VBA查询Active Directory,而不是SQL Management Studio 2012中的链接服务器?
首先,我已经能够做到这一点,但在许多月前与SQL Server 2005。
这是我正在尝试的查询:
SELECT * FROM OpenQuery( ADSI, 'SELECT displayName, title, department, employeeID, userAccountControl FROM ''LDAP://dc=testdomain'' WHERE objectCategory = ''Person'' AND objectClass = ''user'' AND userAccountControl=512')
这是我得到的错误:
Msg 7321, Level 16, State 2, Line 1 An error occured while preparing the query "SELECT displayName, title, department, employeeID, userAccountControl FROM 'LDAP://dc=testdomain' WHERE objectCategory = 'Person' AND objectClass = 'user' AND userAccountControl=512" for execution against OLE DB provider "ADsDSOObject" for linked server "ADSI".
这个错误消息的问题是它是非常通用的,看起来不会产生任何有用的东西。 我读过的所有内容似乎都是权限问题或查询的语法,我假设它是在上下文中对我的SQL实例login以及在链接服务器中设置安全性的方式。 下面的VBA代码工作正在使用一个非常相似的查询,甚至最简单的查询都不能在链接服务器中工作。 我也有权访问我试图链接到的Active Directory,这是由底部的VBA代码片段certificate的(仅供参考)。 事情是,我相信我有适当的特权到位,为此工作。
然而,很多build议在不同的站点上都涉及到对SQL实例的修改,因为这个服务器还在构build中,所以对长期的影响不是很明显。 我有临时提升权限来build立它。
以下是我设置链接服务器的详细信息和参数:
SQL Server 11.0.5058 Linked Server: ADSI Provider: OLE DB Provider for Microsoft Directory Services Product name: Active Directory Services 2.5 Data source: adsdatasource Provider string: ADsDSOObject Be made using the login's current security context Ole DB Provider Options: Allow in process
但是,我发现的唯一可能会让我从所有其他关于此错误的博客中脱颖而出的是,当我尝试深入查看链接的服务器表和视图时(服务器对象>链接服务器> ADSI>目录>默认>表)。 一旦我点击展开表级别,我得到以下错误:
Failed to retreive data for this request. (Microsoft.SqlServer.Management.Sdk.Sfc) Additional information: An exception occured while executing a Transact-SQL statement or batch. (Microsoft.SqlServer.ConnectionInfo) Cannot obtain the required interface ("IID_IDBSchemaRowset") from OLE DB provider "ADsDSOObject" for linked server "ADSI". (Microsoft SQL Server, Error: 7301)
这个IID_IDBSchemaRowset似乎是我唯一的领先,但是这看起来像是一个深沉的黑暗的兔子洞,不知道这是我需要去的地方。 帮帮我!
以供参考
'References: Microsoft ActiveX Data Objects 2.8 Library Public Sub testADSI() On Error Resume Next Dim cn As ADODB.Connection Dim cmd As ADODB.Command Dim rs as ADODB.Recordset Dim MySql as String Dim n as Integer Set cn = New ADODB.Connection Set cmd = New ADODB.Command Set rs = New ADODB.Recordset cn.Provider = "ADsDSOObject" cn.Open "Active Directory Provider" Set cmd.ActiveConnection = cn cmd.Properties("Page Size")= 1000 MySql = "SELECT displayName, title, department, employeedID, userAccountControl " & _ "FROM 'LDAP://dc=testdomain' " _ & "WHERE objectCategory = 'Person' AND " & _ "objectClass = 'user' AND " & _ "userAccountControl=512" rs.Open MySql, cn, 1 If rs.RecordCount > 0 Then MsgBox "Sucess! " & rs.RecordCount & " records found!" Else MsgBox "No records" End IF End Sub
如果您在链接服务器的“安全设置”页面中使用“无需使用安全上下文”选项,则可能会发生这种情况。 这导致进行匿名LDAP调用。 目前(Server 2008或更高版本)匿名LDAP操作默认是不允许的。
我的testing显示“使用login的安全上下文”选项使LDAP调用在SQL服务器服务正在运行的凭据。
我可能会build议使用“使用login的安全上下文”,映射本地login到远程用户或只需input默认凭据(对话框中的选项4):

在所有情况下,我都build议为链接服务器使用专用的AD用户帐户。
请注意,您正在查询敏感属性,如userAccountControl。 默认情况下,常规域用户无法读取此属性,即您的查询可能不会返回完整的结果集。 您可以通过使用专用的AD帐户来解决此问题,并在适用的情况下为userAccountControl属性授予READ权限。
另外我会build议不要使用无服务器绑定。 至less指定域名:
LDAP://mydomain.local/dc=mydomain,dc=local
这可以帮助您避免LDAP响应缓慢和/或数据不一致。