如何使用C#和ADODB查询Active Directory?

时间:2009-07-16 21:10:33

标签: c# active-directory adodb

寻找使用C#通过ADODB连接到Active Directory的示例。

我的目标是能够运行查找以根据用户属性(用户ID,电子邮件地址等)中的用户验证用户在Active Directory中是否有效。

[我想强调的是,使用ADODB是一个要求,使用DirectoryServices不是一个有效的响应。]

我当前的方法无效(cmd.Execute位出现异常):

object parms = null;
object recs = null;
ADODB.Connection conn = new ADODB.Connection();
ADODB.Command cmd = new ADODB.Command();
ADODB.Recordset rs = new ADODB.Recordset();

conn.Open("Provider=ADsDSOObject",obfsUser,obfsPass,0);

cmd.ActiveConnection = conn;
cmd.CommandText = "<LDAP://OU=obfsOU,DC=obfsDC,DC=corp,DC=Net>;;name;subtree";
rs = cmd.Execute(out recs, ref parms, 0);

我不确定是否/我应该在哪里提供服务器引用,我不确定参数传递给cmd.Execute方法的参数应该是什么。没有大量文档通过ADODB从C#连接到ActiveDirectory。

conn.State返回1,所以我相信我正在建立一个有效的连接。我认为问题在于传递给cmd.Execute()方法的参数。

3 个答案:

答案 0 :(得分:4)

ScottCher的答案有效,但它有局限性,特别是你不能处理1000记录的结果限制。要做到这一点,唯一的方式是使用一个Command对象,相信我,这是一个雷区,因为(a)没有关于C#接口的良好文档,并且(b)有令人难以置信的在撰写本文时,没有完整的解决方案可以用谷歌搜索。

我已经花了最后一天的时间,并且有一些工作,我想回馈我所阅读的所有来源与各种各样的点点滴滴。

首先,正如大量地方所指出的那样(遗憾的是只有VB示例!),如果你没有做一些特别的事情,那么所有ADSI查询都限制在1000行结果中。避免这种情况的关键是在Command对象上设置“页面大小”属性。我们将在一秒内完成,但首先我们需要使用Command来使基本查询工作。如果您在此线程中使用原始代码,则会在cmd.Execute上出现异常,抱怨参数不匹配。你会认为传入null作为ref对象就足够了,特别是因为LDAP语法没有(显然)有参数。

我在两个地方找到了答案。首先,即使您没有明确指定参数,LDAP SQL语法中的“:”似乎足以使ADO认为需要参数。奇怪,但看似真实。其次,指定“无参数”情况的CORRECT方式是将值设置为Type.Missing,而不是null,如:

object parms = Type.Missing;

这是让Execute不抛出异常的关键。

现在有了一个工作命令,我们现在可以解决1000行限制。通过在Command上指定“Page Size”属性来“简单”,但是从C#接口可以看出它与C#属性不同。您需要将它放入Properties集合中,但是这不会公开一个很好的集合接口来实现它。经过一些试验和错误后,正确的语法是:

cmd.Properties["Page Size"].Value = 500;

我认为页面大小究竟是什么并不重要(仍在使用它),但将其设置为足以告诉ADSI获得所有结果。我衷心希望这对某人有所帮助。

答案 1 :(得分:2)

这很有效。

希望这可以帮助其他人有同样的需求和问题。

[注意缺少ADODB.Command对象以及使用SQL格式代替ADSI格式的查询。]

object recs;

ADODB.Connection conn = new ADODB.Connection();
ADODB.Recordset rs = new ADODB.Recordset();

// You may need to provide user id and password instead of empty strings        
conn.Open("Provider=ADsDSOObject", "", "", 0);

// replace <> elements with your server name and OU/DC tree org
string server = "<enter your server name here>";
string start = "OU=<blah>,DC=<blah>,DC=<blah>,DC=<blah>";
string where = "objectClass = '*'";
string qry = string.Format("SELECT cn FROM 'LDAP://{0}/{1}' WHERE {2}", server, start, where);

rs = conn.Execute(qry, out recs, 0);

for (; !rs.EOF; rs.MoveNext())
{
    Console.WriteLine(rs.Fields["cn"].Value.ToString());
}

答案 2 :(得分:0)

查看Richard Mueller在Active Directory上的网站 - 他特别提供了ADO ADO搜索提示页面:

http://www.rlmueller.net/ADOSearchTips.htm

他的网站上还有一大堆优秀的参考资料,例如具有所有AD属性及其特征的Excel工作表。

强烈推荐!

马克