2011-04-08 93 views
0

我有一些C#代碼試圖使用提供的計算機名進行LDAP搜索,以確定計算機帳戶是否被禁用。大部分代碼取自this SO question。如果我禁用AD中的帳戶並且在活動的計算機上爲false,示例鏈接中的代碼工作良好並且正確顯示爲true。問題是我不能按照它最初提供的方式完全使用代碼,它必須以我在下面粘貼它的方式使用。下面的代碼的問題是它總是返回false,它傳遞給它的計算機名稱似乎並不重要。我也意識到,foreach循環可能不需要,因爲我只是想找到一臺計算機。C#布爾沒有正確設置

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

您獲得'結果'有多少結果?爲什麼你不能只使用IsDisabled =((userAccountControl&2)> 0); ? – RQDQ 2011-04-08 15:54:03

+0

你的問題是什麼? – Jason 2011-04-08 15:55:40

+1

爲什麼你將IsDisabled作爲參數傳遞,如果你正在更新值並返回它?爲什麼不在本地範圍內聲明它? – Infotekka 2011-04-08 16:00:28

回答

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; 
} 

很明顯,你可以代替拋出一個異常,用更合適的東西...

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); 
+0

是的,這是一個很好的電話,他甚至說他不確定他需要循環,因此應該放棄。你甚至可以完全刪除IsDisabled,並簡單地'return(result!= null)&&((userAccountControl&2)> 0);' – Infotekka 2011-04-08 16:12:03

+0

@Infotekka我喜歡在調試器中查看結果。 :) – jfs 2011-04-08 16:13:24

+0

哈,是的好點 - 有時我會被壓縮我的代碼帶走。 – Infotekka 2011-04-08 16:15:58

1

您應該逐步通過調試器來確認這一點,但如果你調用這個函數並且搜索沒有得到任何結果時,如果你傳遞了false作爲第一個參數,那麼你的函數將返回與你通過IsDisabled開頭的值相同的false值。