2011-08-23 22 views
0

我需要重構一個處理LDAP,ADODB和ActiveDirectory從VBS到C#的VBS。我卡住的部分是連接(剛剛開始,已經卡住......很棒)。這是原始的源將VBS中的LDAP/AD腳本重構爲C#

Set objRootDSE = GetObject("LDAP://RootDSE") 
strConfig = objRootDSE.Get("configurationNamingContext") 
strDNSDomain = objRootDSE.Get("defaultNamingContext") 

Set adoCommand = CreateObject("ADODB.Command") 
Set adoConnection = CreateObject("ADODB.Connection") 
adoConnection.Provider = "ADsDSOObject" 

adoConnection.Open "Active Directory Provider" 
adoCommand.ActiveConnection = adoConnection 

strQuery = "<LDAP://dm1.com.local/OU=CN,OU=Users,OU=CMS Organizational,OU=CMS_Users_and_Groups,DC=cms,DC=local>;(&(objectCategory=person)(objectClass=user)(!useraccountcontrol:1.2.840.113556.1.4.803:=2));distinguishedName,lastLogon,whenCreated;subtree" 

adoCommand.CommandText = strQuery 
adoCommand.Properties("Page Size") = 100 
adoCommand.Properties("Timeout") = 60 
adoCommand.Properties("Cache Results") = False 

Set adoRecordset = adoCommand.Execute 

和C#像這樣

DirectoryEntry dse = new DirectoryEntry("LDAP://RootDSE"); 
string config = dse.Properties["configurationNamingContext"].Value.ToString(); 
string domain = dse.Properties["defaultNamingContext"].Value.ToString(); 
Connection connection = new Connection(); 
connection.Provider = "ADsDSOObject"; 
connection.Open("ADsDSOObject", "", "", 0); 

object records, parameters = ""; 

ADODB.Command command = new Command(); 
command.ActiveConnection = connection; 
command.CommandText = "<LDAP://dm1.com.local/OU=CN,OU=Users,OU=CMS Organizational,OU=CMS_Users_and_Groups,DC=cms,DC=local>;(&(objectCategory=person)(objectClass=user)(!useraccountcontrol:1.2.840.113556.1.4.803:=2));distinguishedName,lastLogon,whenCreated;subtree"; 
command.Execute(out records, ref parameters, 0); 

它給我的錯誤

Interface not supported (Provider) 
at ADODB.CommandClass.Execute(Object& RecordsAffected, Object& Parameters, Int32 Options) 
at Adug.Program.Main(String[] args) in E:\...\Program.cs:line 66 

回答

4

我通過ADO查詢LDAP沒有經驗,但我有成功使用了以下代碼(在此簡化),其使用DirectorySearcher

DirectoryEntry directoryEntry = new DirectoryEntry(
     config.DirectoryConnectionString, 
     config.ActiveDirectoryUserName, 
     config.GetPassword(), 
     AuthenticationTypes.Secure); 
DirectorySearcher ds = new DirectorySearcher(directoryEntry); 

ds.PropertiesToLoad.Add("cn"); 
ds.PropertiesToLoad.Add("sAMAccountName"); 
ds.PropertiesToLoad.Add("mail"); 
ds.PropertiesToLoad.Add("displayName"); 

ds.Filter = "(objectClass=user)"; 

foreach (SearchResult result in ds.FindAll()) 
{ 
    string displayName = String.Empty; 
    DirectoryEntry entry = result.GetDirectoryEntry(); 
    if (entry.Properties.Contains("displayName")) 
      if (entry.Properties["displayName"].Count > 0) 
       displayName = entry.Properties["displayName"][0].ToString(); 
} 
+2

將ds.Filter從objectClass = user更改爲objectCategory = person會導致索引搜索,並且速度會更快。 – Dscoduc

+0

謝謝@Dscoduc,我對DirectorySearcher的知識非常缺乏,總是很好學習新的東西。 –

+0

實際上,您應該同時使用 - (&(objectCategory = person)(objectClass = user))。 Windows 2008+ DCs在objectClass上有一個強制索引,所以它沒有什麼問題,但是,你會得到其他東西(例如計算機,信任等)。 –

0

使用System.DirectoryServices命名空間是訪問.NET中Active Directory的首選方法。 丹尼爾B的答案應該讓你朝着正確的方向前進。