Active Directory Service Interface (ADSI) 是一組植基於 COM 技術上的應用程式開發介面,程式開發人員可以利用這些介面來連接並存取 Active Directory,並執行查詢,更新或刪除等管理功能,ADSI同時可支援以LDAP(輕量級目錄存取協定)為主的目錄服務(例如Novell Directory Service),以及以 Windows NT 網域為主所組成的 WinNT 網域目錄。

介面結構

ADSI 由 COM 以及原生函式庫所組成,並封裝在 activeds.dll 檔案中,部份則被封裝在 advaip32.dll 中,以 COM 原生介面方式呈現,以提供給 C/C++ 程式語言透過 COM 介面來取用,不過由於所有的原生介面均支援 COM Automation,因此 Visual Basic 或是 .NET Framework 的語言也可以利用 COM Interop 能力存取 ADSI 中的介面。

原生介面 (Native interfaces)

activeds.dll 中封裝了幾個 ADSI 中最核心的介面:

activeds.dll 亦提供了幾個依物件不同而實作的介面,像是:

在使用 ADSI 之時,有時會需要一些工具型功能,像是 DOMAIN\user 和 User Principal Name 間的轉換,或是取得系統資訊等,ADSI 也提供了這類的介面:

這些介面多是使用 C/C++ 程式語言來存取,若是使用 VB 或是 Scripting Language 時,則可以使用另外的方法來存取。

' Get user object from Active Directory.
Dim mach As IADsContainer
Dim usr as IADsUser

On Error GoTo Cleanup
Set mach = GetObject("WinNT://MyMachine,Computer")
Set usr = mach.Create("user","jeffsmith")
usr.SetInfo

Cleanup:
    If(Err.Number<>0) Then
        MsgBox("An error has occurred. " & Err.Number)
    End If
    Set mach = Nothing
    Set usr = Nothing
// binding Active Directory using C++ and native interface.
IADs *pObject;
HRESULT hr;

// Initialize COM.
CoInitialize(NULL);

hr = ADsGetObject(L"LDAP://CN=jeffsmith,DC=fabrikam,DC=com", 
        IID_IADs,
        (void**) &pObject);
if(SUCCEEDED(hr))
{
    // Use the object.

    // Release the object.
    pObject->Release()
}

// Uninitialize COM.
CoUninitialize();

函式

ADSI 除了介面以外,也將部份功能使用函式方式顯露,以簡化呼叫原生介面需要處理的工作,較重要且經常被使用的有:

下列的例子,是使用 ADsOpenDSObject() 取得 IADs 物件的範例程式碼:

IADs *pObject;
LPWSTR szUsername = NULL;
LPWSTR szPassword = NULL
HRESULT hr;

// Insert code to securely retrieve the username and password.

hr = ADsOpenObject(L"LDAP://CN=Jeff,DC=Fabrikam,DC=com",
                   "jeffsmith",
                   "etercespot",
                   ADS_SECURE_AUTHENTICATION, 
                   IID_IADs,
                   (void**) &pObject);

.NET Framework 原生介面

.NET Framework 中,另外提供了一個 .NET 專用的 ADSI 介面程式庫 System.DirectoryService.dll,程式開發人員可以加入此程式庫的參考來取得 ADSI 的功能,在這個原生類別庫中,封裝了兩個類別,作為存取 Active Directory 的入口之用。

截至 .NET Framework 3.5 為止,ADSI 在 Managed Class Library 中有四個命名空間:

下列為使用 C# 存取 DirectoryEntry 的範例程式碼:

DirectoryEntry ent = new DirectoryEntry();
DirectoryEntry ou = ent.Children.Find("OU=Consulting");

// Use the Add method to add a user to an organizational unit.
DirectoryEntry usr = ou.Children.Add("CN=New User","user");
// Set the samAccountName, then commit changes to the directory.
usr.Properties["samAccountName"].Value = "newuser"; 
usr.CommitChanges();

目錄服務提供者 (directory service provider)

ADSI 因為是使用了 LDAP 以及開放式目錄等標準,因此只要目錄服務的平台是以開放式目錄標準實作 IADsNamespace 與其他目錄服務提供者介面時,即可由 ADSI 來支援,目前 ADSI 有五種提供者:

OLE DB Provider for Directory Services

除了 ADSI 原生介面外,微軟也為了 SQL Server 或是 ADO 應用程式開發人員發展了可使用 ADO 來存取 Active Directory 的驅動程式,此驅動程式使用 OLE DB 來開發,並且使用類似 SQL 指令的方式來存取 Active Directory,此驅動程式稱為 OLE DB Provider for Directory Service,其 COM 的 Prog ID 為 ADsDSOObject

下例為使用 ADO 存取 Active Directory 的範例程式碼:

Dim Con As New Connection
Dim rs As New Recordset
Dim command As New Command
Dim usr As IADsUser

' Replace department for all users in OU=sales.
Set con = Server.CreateObject("ADODB.Connection")
con.Provider = "ADsDSOObject"
 
Set command = CreateObject("ADODB.Command")
Set command.ActiveConnection = con
 
command.CommandText = "SELECT AdsPath, cn FROM 'LDAP://OU=Sales,DC=Fabrikam,DC=com' WHERE objectClass = 'user'"
 
command.Properties("searchscope") = ADS_SCOPE_ONELEVEL
Set rs = command.Execute
While Not rs.EOF
    Set usr = GetObject(rs.Fields("AdsPath").Value)
    usr.Put "department", "1001"
    usr.SetInfo
    rs.MoveNext
Wend

下列指令為使用 SQL Server 查詢來合併存取 Active Directory 的指令碼[1]

-- create a linked server to active directory interface
EXEC sp_addlinkedserver 'ADSI', 'Active Directory Services 2.5', 'ADSDSOObject', 'adsdatasource' 

-- configure SQL Server to allow ad-hoc query and openquery statement.
EXEC sp_configure 'show advanced options', 1
reconfigure with override

EXEC sp_configure 'Ad Hoc Distributed Queries', 1 
reconfigure 

-- execute query via OpenQuery() statement
SELECT * FROM OpenQuery(ADSI, 'SELECT * FROM ''LDAP://DC=kodyaz,DC=com'' WHERE objectCategory=''user'' ') 

SELECT * FROM OpenQuery(ADSI, 'SELECT mail, displayName, userPrincipalName FROM ''LDAP://DC=kodyaz,DC=com'' WHERE objectCategory=''user'' ')

開發 Directory-Enabled 應用程式時可用的工具

由於 ADSI 和 Active Directory 的特性,開發人員若沒有使用適當的工具時,很難發展與目錄服務連結 (directory-enabled) 的應用程式,因此微軟為 Active Directory 提供了兩種工具:

參考資料

內容參考:

  1. ^ Running Active Directory Services Queries Using MS SQL Server OPENQUERY Command. [2009-01-01]. (原始内容存档于2009-01-05). 
  2. ^ AD Explorer. [2009-01-01]. (原始内容存档于2008-12-18). 
  3. ^ Adsiedit Overview: Active Directory. [2009-01-01]. (原始内容存档于2008-12-30). 

文章參考:

  1. MSDN Library: Active Directory Service Interface页面存档备份,存于互联网档案馆
  2. Directory Service in .NET Framework页面存档备份,存于互联网档案馆