在SSIS包中使用VB.NET,如何在多个Active Directory域(在同一个林中)中填充SQL Server表?
答案 0 :(得分:2)
我使用类似于Siva方法的查询的路线,除了代替链接服务器查询,我使用ADSI提供程序。 Active Directory SSIS Data Source
SELECT
distinguishedName
, mail
, samaccountname
, Name
, employeeNumber
, objectSid
, userAccountControl
, givenName
, middleName
, sn
FROM
'LDAP://DC=domain,DC=net'
WHERE
sAMAccountType = 805306368
ORDER BY
sAMAccountName ASC
引用帖子中的代码将从给定域中提取所有用户。在从NTEXT转换为TEXT到String之后,我使用专有名称和DirectoryServices程序集通过其专有名称枚举用户的所有第一个订单组。它不涉及嵌套组。方便的是,该帖子涵盖了2005年的SSIS实现,因此逻辑在VB中。
答案 1 :(得分:1)
如果这是一个选项,这是在SQL Server上使用链接服务器的一个可能选项,实际上并不需要VB.NET
。下面给出的查询仅用于语法参考。请阅读链接以正确使用这些SQL Server对象。
您可以在SQL Server上设置链接服务器,以使用OLE DB Provider for Microsoft Directory Services
连接到 Active Directory 。下面是一个示例脚本,它将设置链接服务器并将其映射到可以访问Active目录的登录名。
sp_addlinkedserver (Transact-SQL)
的用法sp_addlinkedsrvlogin (Transact-SQL)
的用法USE [master];
GO
EXEC master.dbo.sp_addlinkedserver
@server = N'ADSI'
, @srvproduct = N'ADSI'
, @provider = N'ADsDSOObject'
, @datasrc = N'adsdatasource'
, @provstr = N'ADSDSOObject';
GO
EXEC master.dbo.sp_addlinkedsrvlogin
@rmtsrvname = N'ADSI'
, @useself = N'False'
, @locallogin = NULL
, @rmtuser = N'<User account goes here...>'
, @rmtpassword = '<Password goes here...>';
GO
然后,您可以使用OpenQuery在Active Directory中查询用户信息。请阅读MSDN上的以下链接,了解有关如何制定查询的更多信息。
Search Active Directory - Distributed Query
SELECT *
FROM OPENQUERY
( ADSI
, ' SELECT *
FROM ''LDAP://<OU path goes here...>''
WHERE objectClass = ''user'''
);
您可以将此查询设置为SQL Server视图,然后从SSIS包中的数据流任务上的 OLE DB源调用该视图,然后重定向输出到 OLE DB目的地以填充数据库表。
答案 2 :(得分:1)
以下是一个示例逻辑,它借助VB.NET在脚本组件中配置为源,将Active Directory用户信息从一个域导入数据库表。此样本在SSIS 2012中进行了测试,但应在SSIS 2008及更高版本中使用。此逻辑在SSIS 2005中不起作用,因为命名空间 System.DirectoryServices.AccountManagement
仅在.NET framework 3.5中引入,SSIS 2005使用.NET Framework 2.0
创建SSIS包。此示例使用SSIS 2012。
创建一个连接到SQL Server数据库的 OLEDB Connection Manager
。如果您创建了数据源,请将数据源添加到包的连接管理器选项卡中。
将 Data Flow Task
拖放到控制流标签上。
双击 Data Flow Task
切换到数据流标签。
将 Script Component
拖放到数据流标签上。
在选择脚本组件类型对话框中选中 Source
,然后点击确定。
双击脚本组件以打开脚本转换编辑器。点击 Inputs and Outputs
标签页。
将输出重命名为ActiveDirectory以提供有意义的名称。
选择“输出列”,然后单击“添加列”以添加下面提到的每个列。这只是为了说明这个例子。您可能需要添加首选列。
Name Data Type Length
----------------- ------------------------ ------
FirstName Unicode string [DT_WSTR] 255
LastName Unicode string [DT_WSTR] 255
SAMAccountName Unicode string [DT_WSTR] 255
UserPrincipalName Unicode string [DT_WSTR] 255
定义列后,点击 Script
标签页
将ScriptLanguage更改为 Microsoft Visual Basic 2010
在Solution Explorer上,右键单击Script Component项目,然后单击 Add Reference...
。添加对以下命名空间的引用。
System.DirectoryServices
System.DirectoryServices.AccountManagement
<Your domain name goes here>
部分替换为适当的域名。代码在 PreExecute
方法中初始化 PrincipalContext 和 PrincipalSearcher 对象,然后将它们放在 PostExecute
方法。 CreateNewOutputRows方法循环遍历AD中的每一行以获取用户属性信息。#Region "Imports"
Imports System
Imports System.Data
Imports System.Math
Imports Microsoft.SqlServer.Dts.Pipeline.Wrapper
Imports Microsoft.SqlServer.Dts.Runtime.Wrapper
Imports System.DirectoryServices.AccountManagement
Imports System.DirectoryServices
#End Region
<Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute()> _
<CLSCompliant(False)> _
Public Class ScriptMain
Inherits UserComponent
Dim principalContext As PrincipalContext = Nothing
Dim principalSearcher As PrincipalSearcher = Nothing
Public Overrides Sub PreExecute()
principalContext = New PrincipalContext(ContextType.Domain, "<Your domain name goes here>")
principalSearcher = New PrincipalSearcher(New UserPrincipal(principalContext))
MyBase.PreExecute()
End Sub
Public Overrides Sub PostExecute()
principalContext = Nothing
principalSearcher = Nothing
MyBase.PostExecute()
End Sub
Public Overrides Sub CreateNewOutputRows()
For Each principal As Principal In principalSearcher.FindAll()
Dim entry As DirectoryEntry = TryCast(principal.GetUnderlyingObject(), DirectoryEntry)
With ActiveDirectoryBuffer
.AddRow()
If entry.Properties("givenName").Value IsNot Nothing Then
.FirstName = entry.Properties("givenName").Value.ToString()
Else
.FirstName = "Unknown"
End If
If entry.Properties("sn").Value IsNot Nothing Then
.LastName = entry.Properties("sn").Value.ToString()
Else
.LastName = "Unknown"
End If
If entry.Properties("samAccountName").Value IsNot Nothing Then
.SAMAccountName = entry.Properties("samAccountName").Value.ToString()
Else
.SAMAccountName = "Unknown"
End If
If entry.Properties("userPrincipalName").Value IsNot Nothing Then
.UserPrincipalName = entry.Properties("userPrincipalName").Value.ToString()
Else
.UserPrincipalName = "Unknown"
End If
End With
Next
End Sub
End Class
关闭脚本转换编辑器。
将OLE DB目标拖放到“数据流”选项卡上。将脚本组件连接到OLE DB目标以重定向源输出。选择适当的OLE DB连接管理器和应插入数据的表。
此示例仅提供来自一个域的加载信息。如果您有多个域,则可以将它们存储在表中。获取所有域列表的信息,并使用控制流上可用的 Foreach Loop Container
循环遍历每个域,并使用上述方法获取用户信息。也许在VB.NET中有更好的方法可以做到这一点。
您可以在以下MSDN链接中找到Active Directory用户属性的完整列表。您需要单击链接以查找LDAP-Display-Name。
这是另一个可能有助于获取用户对象属性的链接