搜索LDAP并创建CSV文件

时间:2011-10-04 08:13:42

标签: c# ldap

我编写了以下程序,它连接到两个LDAP存储,比较属性并根据结果创建一个新的csv文件。我遇到了一个问题。

以下是代码:

        //Define LDAP Connection
        string username = "****";
        string password = "*****";
        string domain = "LDAP://****";

        //Define LDAP Connection 
        string ABSAusername = "****";
        string ABSApassword = "****";
        string ABSAdomain = "LDAP://****";

        //Create Directory Searcher
        DirectoryEntry ldapConnection = new DirectoryEntry(domain,username,password);
        ldapConnection.AuthenticationType = AuthenticationTypes.Anonymous;
        DirectorySearcher ds = new DirectorySearcher(ldapConnection);
        ds.Filter = "((EmploymentStatus=0))";
        ds.SearchScope = System.DirectoryServices.SearchScope.Subtree;

        //Create Directory Searcher
        DirectoryEntry ABSAldapConnection = new DirectoryEntry(ABSAdomain, ABSAusername, ABSApassword);
        ABSAldapConnection.AuthenticationType = AuthenticationTypes.Anonymous;
        DirectorySearcher ABSAds = new DirectorySearcher(ABSAldapConnection);
        ABSAds.Filter = "((&(EmploymentStatus=3)(EmploymentStatusDescription=Active))";
        ABSAds.SearchScope = System.DirectoryServices.SearchScope.Subtree;

        ds.PropertiesToLoad.Add("cn");
        ds.PropertiesToLoad.Add ("uid");
        ds.PropertiesToLoad.Add("sn");
        ds.PropertiesToLoad.Add("PersonnelAreaDesc");
        ds.PropertiesToLoad.Add("JobcodeID");
        ds.PropertiesToLoad.Add("CostCentreID");
        ds.PropertiesToLoad.Add("CostCentreDescription");
        ds.PropertiesToLoad.Add ("givenName");
        ds.PropertiesToLoad.Add ("EmploymentStatus");
        ds.PropertiesToLoad.Add("EmploymentStatusDescription");

        ABSAds.PropertiesToLoad.Add("uid");
        ABSAds.PropertiesToLoad.Add("EmploymentStatus");

        ABSAds.Sort = new SortOption("uid", SortDirection.Ascending);
        ds.Sort = new SortOption("cn", SortDirection.Ascending);

        SearchResultCollection absaUsers = ds.FindAll();
        SearchResultCollection srcUsers = ds.FindAll();

        sw.WriteLine("Action" + "," + "uid" + "," + "Business Area" + "," + "employeeNumber" + "," + "First Name" + "," + "Last Name" + "," + "JobCodeID" + "," + "costCentreID" + "," + "costCentreDescription" + "," + "FullName" + "," + "EmploymentStatus" + "," + "EmploymentStatusDescription" );
        sw.WriteLine("");

        foreach (SearchResult users in srcUsers)
        {


            string cn = users.Properties["cn"][0].ToString();
            string sn = users.Properties["sn"][0].ToString();
            string userID = users.Properties["uid"][0].ToString();
            string description = users.Properties["PersonnelAreaDesc"][0].ToString();
            // string jobCodeID = users.Properties["JobcodeID"][1].ToString();
            string CostCentreID = users.Properties["costCentreID"][0].ToString();
            string CostCentreDescription = users.Properties["CostCentreDescription"][0].ToString();
            string givenName = users.Properties["givenName"][0].ToString();
            string employmentStatus = users.Properties["EmploymentStatus"][0].ToString();
            string EmploymentStatusDescription = users.Properties["EmploymentStatusDescription"][0].ToString();

            foreach (SearchResult absaUser in absaUsers)
            {
                string absaUID = absaUser.Properties["uid"][0].ToString();
                string absaEmploymentStatus = absaUser.Properties["EmploymentStatus"][0].ToString();

                if (cn == absaUID)
                {
                    if (absaEmploymentStatus == "3")
                    {

                        sw.WriteLine(cn);
                    }
                }
            }
        }


        sw.Flush();
        sw.Close();
        sw.Dispose();
    }
}

我创建了两个foreach循环,在第一个循环中我将变量分配给字符串,而在第二个foreach循环中我与IF语句进行比较。我想要做的是:如果一个LDAP中的uid等于另一个ldap中的uid,并且如果第一个ldap中的用户状态= 0但是第二个ldap中的用户状态= 3:那么我想从第一个ldap打印出符合该条件的用户。

如果你查看我的代码,我做错了吗?该程序的输出目前约有10个用户,每个用户至少重复100次。

提前致谢。

2 个答案:

答案 0 :(得分:5)

这段代码显然有几个问题......

1)首先,您要创建两次相同的搜索结果:

   SearchResultCollection absaUsers = ds.FindAll();
   SearchResultCollection srcUsers = ds.FindAll();

因此,如果该搜索者找到10个用户,则此处有两个相同的10个用户的集合。

2)然后你使用了嵌套的foreach循环,所以你基本上是逐个查看第一个集合的所有结果,并且对于每个条目,你枚举整个第二个集合 - 基本上在两者之间做一个笛卡尔积集合。所以这就是为什么你最终会得到10 x 10 = 100个用户.....

3)您似乎缺少某种限制/条件,只能从您的第二个/内部结果集中选择与某些方式匹配外部/第一个结果集的那些元素。只要您没有这样的条件,您将始终从第一个结果集的每个元素的第二个结果集中获得所有结果=经典的笛卡尔积。不知何故,你想根据第一个结果集......

中的某些东西,只选择第二组中的某些元素

答案 1 :(得分:2)

你在以下地方错过了休息时间:

if (cn == absaUID && absaEmploymentStatus == "3")
{
    sw.WriteLine(cn);
    break;
}