我有一些C#代码尝试使用提供的计算机名进行LDAP搜索,以确定计算机帐户是否已被禁用。大部分代码都来自this SO question。如果我在AD中禁用帐户而在活动的计算机上禁用false,则示例链接中的代码运行良好并正确显示true。问题是我不能以最初呈现的方式完全使用代码,它必须以我在下面粘贴它的方式使用。下面代码的问题是它总是返回false,你传递给它的计算机名称似乎并不重要。我也意识到foreach循环可能是不必要的,因为我只是想找一台电脑。
using System;
using System.DirectoryServices;
namespace DynamicNamespace
{
public class DynamicClass
{
public System.Boolean DynamicMethod(System.Boolean IsDisabled, System.String ComputerName)
{
//the string should be your a DC(domain controller)
const string ldap = "LDAP://server-name";
//DirectoryEntry is used for manipulating objects (users, computers)
DirectoryEntry entry = new DirectoryEntry(ldap);
//DirectorySearcher responds to a filter method for LDAP searches
//http://www.tek-tips.com/faqs.cfm?fid=5667 has a decent query guide
DirectorySearcher dSearch = new DirectorySearcher(entry);
//SAM Account Name was showing a $ sign at one point, using * for wildcard
dSearch.Filter = String.Format("samAccountName={0}*", ComputerName);
dSearch.PropertiesToLoad.Add("samAccountName");
dSearch.PropertiesToLoad.Add("userAccountControl");
SearchResultCollection results = dSearch.FindAll();
foreach (SearchResult result in results)
{
int userAccountControl = Convert.ToInt32(result.Properties["userAccountControl"][0]);
string samAccountName = Convert.ToString(result.Properties["samAccountName"][0]);
bool disabled = ((userAccountControl & 2) > 0);
if (disabled == false)
{
IsDisabled = false;
}
else
{
IsDisabled = true;
}
}
return IsDisabled;
}
}
}
答案 0 :(得分:2)
您可能正在接收多个SearchResult,因为您使用循环IsDisabled
将被多次分配。
根据您评论中的link,您正在进行部分匹配:
PARTIAL MATCH......................(attribute={partial value}*)
如果提供的计算机名称准确无误,为什么不使用:
EQUALITY...........................(attribute=value)
然后你可以删除循环:
dSearch.Filter = String.Format("(samAccountName={0})", ComputerName);
dSearch.PropertiesToLoad.Add("samAccountName");
dSearch.PropertiesToLoad.Add("userAccountControl");
SearchResult result = dSearch.FindOne();
bool disabled = (result != null) && ((userAccountControl & 2) > 0);
答案 1 :(得分:1)
你应该单步执行调试器来确认这一点,但是如果你在调用这个函数时将false
作为第一个参数传递并且搜索没有得到任何结果,那么你的函数将会返回您通过false
开始传入的IsDisabled
值相同。
答案 2 :(得分:0)
您的代码没有任何问题,唯一的问题是您没有区分帐户是否存在以及是否存在但是已禁用。
您可以执行以下操作来检测帐户是否不存在,并且您正在执行for循环并不重要,因为就像您说它只执行一次但如果您愿意将其更改为以下...(您必须改变它以满足它可以返回超过1个结果的事实,因为你的搜索过滤器中有一个*)
SearchResultCollection results = dSearch.FindAll();
if (results.Count == 0)
throw new Exception("Account not found.");
else if (results.Count == 1)
{
SearchResult result = results[0];
int userAccountControl = Convert.ToInt32(result.Properties["userAccountControl"][0]);
string samAccountName = Convert.ToString(result.Properties["samAccountName"][0]);
bool disabled = ((userAccountControl & 2) > 0);
if (disabled == false)
{ IsDisabled = false; }
else { IsDisabled = true; }
}
else
throw new Exception("More than 1 result found, please filter");
try
{
bool res = dc.DynamicMethod(false, "Username");
}
catch (Exception ex)
{
if (ex.Message == "Account not found.")
{
//Do Something
}
else
throw ex;
}
显然你可以用更合适的东西替换抛出异常......