[英]SSIS - C# Data Source - Limit Active Directory Search Scope
I am pretty new to C# in general and scripting in SSIS. 对于C#和SSIS中的脚本,我还是很陌生的。
I have recently had to design a solution that will query Active Directory on a once daily basis to provide a snapshot of the users modified and if their member of groups etc have changed. 最近,我不得不设计一种解决方案,该解决方案将每天一次查询Active Directory,以提供已修改用户以及其组成员等是否已更改的快照。 Previously this was done through a flat file solution with a fairly inefficient design. 以前,这是通过设计效率相当低的平面文件解决方案来完成的。
This is to be applied to a DataVault 2.0 which the design is pretty much complete. 这将应用于设计非常完整的DataVault 2.0。
I have a working script that currently collects all off the ad forrest . 我有一个工作脚本,当前可以收集所有广告 。 I am hoping someone could kindly provide some assistance or direction as to how could limit the search scope to only records modified in the l ast 48 hours. 我希望有人可以就如何将搜索范围限制为仅在最近48小时内修改的记录提供一些帮助或指导。 Ideally i would like to pass a parameter of the last successful run time and pass that in as the filter value. 理想情况下,我想传递上一次成功运行时的参数,并将其作为过滤器值传递。
I have attached the relevant code solution without all the useless SSIS per-amble. 我已经附上了相关的代码解决方案,而没有使用所有无用的SSIS。 I am sure it is not the most efficient code being a Data Vault modeller so any assistance and guidance would be greatly appreciated. 我确信这不是Data Vault建模器中最有效的代码,因此,我们将不胜感激任何帮助和指导。
#region Help: Introduction to the Script Component
/* The Script Component allows you to perform virtually any operation that can be accomplished in
* a .Net application within the context of an Integration Services data flow.
*
* Expand the other regions which have "Help" prefixes for examples of specific ways to use
* Integration Services features within this script component. */
#endregion
#region Namespaces
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
//Additional References Required
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
using System.DirectoryServices.AccountManagement;
#endregion
/// <summary>
/// This is the class to which to add your code. Do not change the name, attributes, or parent
/// of this class.
/// </summary>
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
//ITERATION OF THE PROGRAM
public override void CreateNewOutputRows()
{
/*
* Add your code here
* author:
* created: 2017-02-10
* description:
* - Connects to Active Directory and collects desired user information through LDAP. This is then stored in a custom built data table which can be accessed by the SSIS Solution.
* change log:
* - DB 170210: init
*/
//Create Custom Datatable / Columns to store desired Datavalues
DataTable workTable = new DataTable("Ad_Users");
DataColumn workColumn = workTable.Columns.Add("SID", typeof(string));
workTable.Columns.Add("ObjectCategory", typeof(string));
workTable.Columns.Add("ObjectGUID", typeof(string));
workTable.Columns.Add("userPrincipalName", typeof(string));
workTable.Columns.Add("CanonicalName", typeof(string));
workTable.Columns.Add("SAMAccount", typeof(string));
workTable.Columns.Add("DisplayName", typeof(string));
workTable.Columns.Add("Surname", typeof(string));
workTable.Columns.Add("GivenName", typeof(string));
workTable.Columns.Add("UserAccessControl", typeof(Int32));
workTable.Columns.Add("Title", typeof(string));
workTable.Columns.Add("Company", typeof(string));
workTable.Columns.Add("Department", typeof(string));
workTable.Columns.Add("Office", typeof(string));
workTable.Columns.Add("Description", typeof(string));
workTable.Columns.Add("HomeDrive", typeof(string));
workTable.Columns.Add("ScriptPath", typeof(string));
workTable.Columns.Add("WhenCreated", typeof(DateTime));
workTable.Columns.Add("WhenChanged", typeof(DateTime));
workTable.Columns.Add("MemberOf", typeof(string));
**using (var context = new PrincipalContext(ContextType.Domain, "[REDACTED].internal"))
{
using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
{
foreach (var result in searcher.FindAll())
{
DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry;**
int i = 0;
for (i = 0; i < de.Properties["MemberOf"].Count - 1; i++)
{
var sidInBytes = (byte[])de.Properties["ObjectSID"].Value;
var GUID = (byte[])de.Properties["ObjectGuid"].Value;
Guid guid = new Guid(GUID);
DataRow workRow = workTable.NewRow();
//INSERT VALUES INTO DATATABLE
workRow["SID"] = new System.Security.Principal.SecurityIdentifier(sidInBytes, 0);
workRow["ObjectCategory"] = de.Properties["ObjectCategory"].Value;
workRow["ObjectGUID"] = guid;
workRow["userPrincipalName"] = de.Properties["UserPrincipalName"].Value;
workRow["CanonicalName"] = de.Properties["CN"].Value;
workRow["SAMAccount"] = de.Properties["SAMAccountName"].Value;
workRow["DisplayName"] = de.Properties["DisplayName"].Value;
workRow["Surname"] = de.Properties["SN"].Value;
workRow["GivenName"] = de.Properties["GivenName"].Value;
workRow["UserAccessControl"] = de.Properties["userAccountControl"].Value;
workRow["Title"] = de.Properties["Title"].Value;
workRow["Company"] = de.Properties["Company"].Value;
workRow["Department"] = de.Properties["Department"].Value;
workRow["Office"] = de.Properties["physicalDeliveryOfficeName"].Value;
workRow["Description"] = de.Properties["Description"].Value;
workRow["HomeDrive"] = de.Properties["HomeDirectory"].Value;
workRow["ScriptPath"] = de.Properties["ScriptPath"].Value;
workRow["WhenCreated"] = de.Properties["WhenCreated"].Value;
workRow["WhenChanged"] = de.Properties["WhenChanged"].Value;
workRow["MemberOf"] = de.Properties["MemberOf"][i].ToString();
Output0Buffer.AddRow();
Output0Buffer.SID = workRow["SID"].ToString();
Output0Buffer.ObjectCategory = workRow["ObjectCategory"].ToString();
Output0Buffer.ObjectGuid = workRow["ObjectGUID"].ToString();
Output0Buffer.UserPrincipalAccount = workRow["userPrincipalName"].ToString();
Output0Buffer.CanonicalName = workRow["CanonicalName"].ToString();
Output0Buffer.SamAccountName = workRow["SAMAccount"].ToString();
Output0Buffer.DisplayName = workRow["DisplayName"].ToString();
Output0Buffer.Surname = workRow["Surname"].ToString();
Output0Buffer.GivenName = workRow["GivenName"].ToString();
Output0Buffer.UserAccessControl = workRow["UserAccessControl"].ToString();
Output0Buffer.Title = workRow["Title"].ToString();
Output0Buffer.Company = workRow["Company"].ToString();
Output0Buffer.Department = workRow["Department"].ToString();
Output0Buffer.Office = workRow["Office"].ToString();
Output0Buffer.Description = workRow["Description"].ToString();
Output0Buffer.HomePath = workRow["HomeDrive"].ToString();
Output0Buffer.ScriptPath = workRow["ScriptPath"].ToString();
Output0Buffer.WhenCreated = workRow["WhenCreated"].ToString();
Output0Buffer.WhenChanged = workRow["WhenChanged"].ToString();
Output0Buffer.MemberOf = workRow["MemberOf"].ToString();
}
}
}
}
}
}
You want to use the DirectorySearcher
and give it a filter by whenChanged>=someDate
您要使用DirectorySearcher
并通过whenChanged>=someDate
对其进行过滤
var filter = string.Format(
"(&(objectCategory=User)(whenChanged>={0:yyyyMMddHHmmss.0Z}))", //This is the DateTime format it takes.
DateTime.UtcNow.AddHours(-48) // Always use UTC to make life easy. Otherwise you need to change the above time formatting.
);
using (var domain = new System.DirectoryServices.DirectoryEntry())
{
using (var searcher = new DirectorySearcher(domain, filter))
{
foreach (SearchResult result in searcher.FindAll())
{
var de = result.GetDirectoryEntry();
// Now you have a DirectoryEntry. Business as usual.
de.Properties["UserPrincipalName"].Value.Dump();
de.Properties["WhenChanged"].Value.Dump();
de.Properties["MemberOf"].Value.Dump();
}
}
}
As for getting the last successful run , I have never found a good solution in my (albeit only a year) experience in SSIS, other than just storing them somewhere in your own table at the end of a run, and retrieving it on the next run. 关于获得上一次成功运行的信息 ,我(尽管只有一年)在SSIS中从未找到过一个好的解决方案,只是在运行结束时将它们存储在您自己的表中的某个位置,然后在下一次检索时跑。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.