简体   繁体   English

SSIS-C#数据源-限制Active Directory搜索范围

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM