如何使用 C# 和 ADODB 查询 Active Directory?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1140331/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I query Active Directory using C# and ADODB?
提问by ScottCher
Looking for an example of connecting via ADODB to Active Directory using C#.
寻找使用 C# 通过 ADODB 连接到 Active Directory 的示例。
My goal is to be able to run a lookup to verify that a user is valid in Active Directory based on one that of that users attributes (user id, email address, etc).
我的目标是能够运行查找以根据用户属性(用户 ID、电子邮件地址等)之一验证用户在 Active Directory 中是否有效。
[Would like to stress that using ADODB is a requirement for this, using DirectoryServices is not a valid response.]
[想强调的是,使用 ADODB 是对此的要求,使用 DirectoryServices 不是有效的响应。]
My current approach isn't working (exception at cmd.Execute bit):
我目前的方法不起作用(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);
I'm not sure if/where I'm supposed to provide the server reference and I'm not really sure what the parameteres passed into the cmd.Execute method by ref should be. Not a ton of documentation out there for connecting to ActiveDirectory from C# via ADODB.
我不确定是否/应该在哪里提供服务器引用,我不确定通过 ref 传递给 cmd.Execute 方法的参数应该是什么。通过 ADODB 从 C# 连接到 ActiveDirectory 的文档并不多。
conn.State is returning 1 so I believe I am getting an active connection. I think the problem is in the parameters passed to the cmd.Execute() method.
conn.State 返回 1,所以我相信我正在建立一个活动连接。我认为问题在于传递给 cmd.Execute() 方法的参数。
采纳答案by ScottCher
This works.
这有效。
Hope this helps someone else having the same need and problems I had.
希望这可以帮助其他有同样需求和问题的人。
[Note the lack of an ADODB.Command object and the use of SQL format for the query instead of ADSI format.]
[注意缺少 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());
}
回答by marc_s
Check out Richard Mueller's web site on Active Directory - he specifically has a page on ADO Search Tips for AD:
在 Active Directory 上查看 Richard Mueller 的网站 - 他专门有一个关于 AD 的 ADO 搜索提示的页面:
http://www.rlmueller.net/ADOSearchTips.htm
http://www.rlmueller.net/ADOSearchTips.htm
There's also a slew of excellent reference material on his web site, like Excel sheets with all the AD properties and their characteristics.
在他的网站上还有大量出色的参考资料,例如具有所有 AD 属性及其特征的 Excel 表格。
Highly recommended!
强烈推荐!
Marc
马克
回答by tomo
The answer by ScottCher works but it has limitations, notably that you cannot deal with the 1000 record result limit. To do that, the onlyway is to use a Command object, and believe me, that is a minefield because there is (a) no good documentation on the C# interfaces, and (b) there is incredibly no full solution that can be Googled as of this writing.
ScottCher 的答案有效,但它有局限性,特别是您无法处理 1000 条记录结果限制。要做到这一点,唯一的方法是使用 Command 对象,相信我,这是一个雷区,因为 (a) 没有关于 C# 接口的良好文档,并且 (b) 令人难以置信的是没有完整的解决方案可以在 Google 上搜索在撰写本文时。
I have spent the last bunch of days on this, and have something working that I would like to give back to all the sources I have read with various bits and pieces to the puzzle.
我已经花了最后几天的时间来解决这个问题,并且我想将一些工作回馈给我阅读的所有资料来源,其中包含拼图的各种零碎碎片。
First, as noted in a ton of places (sadly with VB examples only!), if you don't do something special then all ADSI queries are limited to 1000 rows of results. The key to avoiding this is to set the "Page Size" property on the Command object. We'll get to that in a sec, but first we need to get the basic query working using a Command. If you use the original code in this thread, you will get an exception on cmd.Execute complaining about parameters mismatching. You would think that passing in null as the ref object would suffice, especially since the LDAP syntax does not (apparently) have parameters.
首先,正如在很多地方所指出的(遗憾的是只有 VB 示例!),如果您不做一些特殊的事情,那么所有 ADSI 查询都被限制为 1000 行结果。避免这种情况的关键是在 Command 对象上设置“页面大小”属性。我们将在一秒钟内解决这个问题,但首先我们需要使用命令使基本查询工作。如果你在这个线程中使用原始代码,你会在 cmd.Execute 上得到一个异常,抱怨参数不匹配。您会认为传入 null 作为 ref 对象就足够了,尤其是因为 LDAP 语法(显然)没有参数。
I found the answer to this in two places. First, even though you are not explicitly specifying parameters, it would seem that the ":" in the LDAP SQL syntax is enough to make ADO think that parameters are required. Odd, but seemingly true. Second, the CORRECT way to specify the "no parameters" case is to set the value to Type.Missing, not null, as in:
我在两个地方找到了答案。首先,即使您没有明确指定参数,LDAP SQL 语法中的“:”似乎足以让 ADO 认为需要参数。奇怪,但似乎是真的。其次,指定“无参数”情况的正确方法是将值设置为 Type.Missing,而不是 null,如下所示:
object parms = Type.Missing;
object parms = Type.Missing;
This was key to getting Execute to not throw an exception.
这是让 Execute 不抛出异常的关键。
Now with a working Command we can now address the 1000 row limit. This is "simply" by specifying the "Page Size" property on the Command but, as it obvious from the C# interface, it is not the same as a C# property. You need to put it into the Properties collection, but this does not expose a nice collection interface to do that with. After some trial and error, the correct syntax is:
现在有了一个有效的命令,我们现在可以解决 1000 行的限制。这是通过在命令上指定“页面大小”属性来“简单”实现的,但是,从 C# 界面可以明显看出,它与 C# 属性不同。您需要将它放入 Properties 集合中,但这并没有公开一个很好的集合接口来执行此操作。经过一些试验和错误,正确的语法是:
cmd.Properties["Page Size"].Value = 500;
cmd.Properties["Page Size"].Value = 500;
I don't think it is important exactly what the page size is (still playing with that) but setting it to something is enough to tell ADSI to get all the results. And I sincerely hope this helps somebody.
我认为页面大小究竟是什么(仍在使用它)并不重要,但将其设置为某个内容足以告诉 ADSI 获得所有结果。我真诚地希望这对某人有所帮助。