top
Loading...
使用ADSI訪問網絡目錄
使用ADSI訪問網絡目錄
中科院軟件所微軟授權培訓中心 張為黨
廊坊陸軍導彈學院教育中心 蔡鐵嶺
前言
在一個大型網絡中,如何標識和定位網絡資源,一直是一個很重要的研究課題。目前人們對這一問題的解決方法,就是使用目錄服務來解決。網絡中的目錄,其功能就相當于我們日常生活中的電話號碼簿。通過電話號碼簿,我們可以通過一個人的名字,找到對應的電話號碼和家庭住址等信息,同樣的道理,給出網絡資源的標識信息,就可以通過目錄服務來找出與該資源相關的其他信息。
目錄服務能夠解決網絡資源的標識和定位問題,各公司都在這一領域投入大量的人員、資金進行研究,并且都推出了各自的目錄服務產品。在一個企業的網絡環境中,可能存在著多種目錄服務,如NDS,Active Directory,如何能夠將這些目錄服務集成在一起,使應用程序能夠使用這些目錄服務,是目前所要解決的問題。
ADSI(Active Directory Service Interfaces,活動目錄訪問接口)是微軟推出的一套目錄服務的訪問接口,其目標是提供一套簡單、統一、開放的接口,通過該接口,應用程序可以管理、使用各種目錄服務。
本文簡要介紹ADSI的基本情況,并且假定讀者已經了解COM、OLE和目錄服務的概念。
目錄服務的現狀
從其作用上看,目錄可以分為兩大類:網絡目錄和特定應用程序中所包含的目錄。
前者的目的是標識與定位網絡上的共享資源,如共享打印機,這種目錄是與具體的應用無關的,就是說,網絡目錄服務提供了一種定位、使用共享資源的手段,任何的網絡用戶,任何應用程序都可以通過這一目錄去使用共享的網絡資源。目前人們所指的目錄就是指這種類型的目錄,產品有微軟的Active Directory, Banyan的StreetTalk,和Novell的NDS。
第二種目錄是與特定應用程序有關的,許多大的應用程序中,如Lotus Notes, cc:Mail, 和Microsoft Mail,都包含了他們自己的目錄,這些目錄只供這些程序自己使用,相互之間沒有共享。應該說隨著目錄技術的成熟和目錄訪問協議的統一,這種類型的目錄要逐漸消亡。
在目前的企業網絡上,可能部署著多個目錄服務,如NDS,Active Directory,Lotus Notes,如圖1所示。

圖1 可能存在的目錄
在同一個網絡環境中存在著多個目錄,帶來很多問題,包括使用、管理,目錄部署等方面,最明顯的一點是,當我們在編寫一個應用軟件時,如果該軟件要用到目錄,那么我們面臨著選擇,使用哪種目錄?因為存在著多種目錄,而各自的訪問方式又各不相同,所以對開發者來說,如果要使用目錄服務的話,不得不對每一種目錄服務編寫相關的代碼,帶來的程序維護上的困難。
實際上對于目錄訪問目前所存在的困境,在軟件業中以前也出現過。回想一下,在數據庫發展的初期,許多廠家都推出了自己的DBMS產品,并且每個廠家都提供了自己的數據庫訪問API接口,這樣數據庫開發人員在開發自己的系統時,不得不針對每一種DBMS來編寫特定的代碼。直到ODBC的出現,才徹底解決了這一問題。
為了解決這一問題,微軟推出了ADSI接口。ADSI實際上是一套COM組件,提供了一套訪問目錄的接口。ADSI之于目錄,其作用就相當于ODBC之于DBMS:通過該接口,開發人員可以使用同一的方法去訪問各種目錄。
ADSI的結構可以用圖2來表示。熟悉ODBC的一眼就可以看出,其結構與ODBC非常相似:SP(Service Provider)相當于ODBC中的Driver,而ADSI層則相當于ODBC中的Driver Manger。

圖2 ADSI的結構
ADSI接口
優點:
開放 每一個目錄開發商都可以按照ADSI規范來實現自己的Service Provider。
應用程序開發簡單 使用ADSI后,應用程序與具體的目錄無關,無論是Active Directory還是NDS,只要他們提供了自己的Provier,應用程序都可以訪問,并且在目錄之間的遷移不需要改動代碼。
支持Java 通過Java COM技術,Java程序可以使用ADSI接口。
安全 ADSI 通過用戶的認證和授權機制來保證安全性。
靈活、可擴展 ADSI是可以通過擴展來支持新的特性,滿足特定的需要。
ADSI對象
前面我們已經提過,ADSI是一套COM組件,在其中封裝了很多目錄對象,微軟稱之為ADSI對象。ADSI對象又分為兩大類:容器對象(Container Objects)和葉子對象(Leaf Objects),這兩類對象其作用分別相當于文件系統的目錄和文件。
ADSI規范中定義了一些標準的容器對象和葉子對象,如果需要的話,還可以再擴展。
資源遍歷
ADSI提供了IADsContainer 接口。通過該接口可以遍歷對象:
Set ou = GetObject(“LDAP://host1/OU=Sales, DC=ArcadiayBay,DC=COM”)
For each obj in ou
Debug.Print obj.Name
Next

資源查找
ADSI是一個OLE DB provider,因此可以使用ADO來查詢目錄中的數據:
Dim con As New Connection, rs As New Recordset
Dim Com As New Command

'Open a Connection object
con.Provider = "ADsDSOObject"
con.Open "Active Directory Provider"

‘Create a command object on this connection
Set Com.ActiveConnection = con
Com.CommandText = "select name from 'LDAP://DC=ArcadiayBay,DC=COM' where objectClass='*' ORDER BY NAME"

'-----------------------------------------
'Set the preferences for Search
'--------------------------------------
Com.Properties("Page Size") = 1000
Com.Properties("Timeout") = 30 'seconds
Com.Properties("searchscope") = ADS_SCOPE_SUBTREE
'--------------------------------------------
'Execute the query
'--------------------------------------------
Set rs = Com.Execute
'--------------------------------------
' Navigate the record set
'----------------------------------------
While Not rs.EOF
Debug.Print rs.Fields( Name ).Value
rs.MoveNext
Wend
使用ADSI的幾個例子
1.遍歷用戶
在實際的應用中,經常需要遍歷某單位的用戶,找到這些用戶的信息以供進一步處理。下面的例子就給出了這方面的例子:找到每個用戶,然后打印該用戶的信息。
dim MyUserContainer as IADsContainer
dim MyUser as IADsUser

set MyUserContainer as GetObject( WinNT://ABX )

for each MyUser in MyUserContainer
PrintUser MyUser.Name, MyUser.TelephoneNumber
next MyUser

2.填加用戶到用戶組
在日常的網絡管理中,出于安全的考慮,經常需要將用戶加入或移出用戶組。下面的例子給出了這種應用:首先判斷用戶是否屬于Manufacturing組,如果不是,則加入。
dim MyUserContainer as IADsContainer
dim MyUser as IADsUser
dim MyGroup as IADsGroup
dim Filter as Variant

Filter = Array( user );

set MyUserContainer = GetOBject( WinNT://ABX )
MyContainer.Filter = Filter filter out all objects except users
set MyGroup = GetObject( WinNT://ABX/Manufacturing_Users )

for each MyUser in MyUserContainer
if not MyGroup.IsMember(MyUser) then
MyGroup.Add(MyUser)
end if
next MyUser
3.啟動和停止網絡服務
下面的例子給出如何通過ADSI接口來控制NT服務。
Set dom = GetObject(“WinNT://ABX”)
Dom.Filter = Array(Computer)
For each comp in dom
comp.Filter = Array(“Service”)
For each svc in comp
If ( svc.Name = Browser ) then
svc.Stop
End if
Next
Next

結束語
企業的網絡環境中可能存在多種網絡目錄,ADSI提供了一套統一、開放的接口,通過這些接口,我們可以管理、訪問這些不同的目錄,減輕了管理、開發方面的負擔。

創建用戶、目錄和站點
關鍵詞:ASP, WSH, NT 作者: white
本講將使用到ADSI,即活動目錄服務接口.可以到15Seconds.com找到一些相關的資料.

1.創建用戶
下面這段代碼在獨立服務器white上創建用戶user1,初始口令user1,用到了ADSI.
Dim Username,UserPass
Dim oDomain,oUser
Username = "user1"
UserPass = "user1"
Set oDomain = GetObject("WinNT://white")
Set oUser = oDomain.Create ("user", UserName)
If (err.number = 0) Then
oUser.SetInfo
oUser.SetPassword UserPass
oUser.SetInfo
Else
WScript.Echo "創建用戶" & UserName & "出錯!"
End If
Set oUser = Nothing
Set oDomain = Nothing

2.創建目錄
使用FileSystemObject創建目錄:
Dim FsObject
Dim tmpFolder
Set FsObject = WScript.CreateObject("Scripting.FileSystemObject")
tmpFolder = "D:userdateuser1"
If Not FsObject.FolderExists(tmpFolder) Then
FsObject.CreateFolder(tmpFolder)
If Err.Number<>0 Then
WScript.Echo "創建目錄" & tmpFolder & "失敗!"
End If
End If
注意在創建目錄前,先檢查了目錄是否存在,如果存在,則不用創建了.

3.創建站點
下面這個子程序負責創建一個WWW站點,各個參數的意義為:站點IP地址,站點根目錄,站點說明,主機名,端口號,計算機名(一搬為LOCALHOST),是否立即啟動,匿名訪問時所使用的帳號,匿名訪問時所用帳號的口令,LOG文件的目錄.
函數返回所建站點在IIS中的序號(在IIS中,所有站點依次編號,第一個為1).
一個調用示例:siteid = ASTCreateWebSite("10.1.3.122","d:userdatauser1","www_user1","","80","LocalHost",True,"IUSR_user1","8iui%#","D:Logfiles")

Function ASTCreateWebSite(IPAddress, RootDirectory, ServerComment, HostName, PortNum, Computer, Start,AnonymousUserName,AnonymousUserPass,LogFileDirectory)
Dim w3svc, WebServer, NewWebServer, NewDir
Dim Bindings, BindingString, NewBindings, Index, SiteObj, bDone
On Error Resume Next
Err.Clear
Set w3svc = GetObject("IIS://" & Computer & "/w3svc")
If Err.Number <> 0 Then
WScript.Echo "無法打開: "&"IIS://" & Computer & "/w3svc" & VbCrlf & "程序將退出."
WScript.Quit (1)
End If

BindingString = IpAddress & ":" & PortNum & ":" & HostName
For Each WebServer in w3svc
If WebServer.Class = "IIsWebServer" Then
Bindings = WebServer.ServerBindings
If BindingString = Bindings(0) Then
WScript.Echo "IP地址沖突:" & IpAddress & ",請檢測IP地址!." & VbCrlf & "取消創建本站點。"
Exit Function
End If
End If
Next

Index = 1
bDone = False

While (Not bDone)
Err.Clear
Set SiteObj = GetObject("IIS://"&Computer&"/w3svc/" & Index)
If (Err.Number = 0) Then
Index = Index + 1
Else
Err.Clear
Set NewWebServer = w3svc.Create("IIsWebServer", Index)
If (Err.Number <> 0) Then
Index = Index + 1
Else
Err.Clear
Set SiteObj = GetObject("IIS://"&Computer&"/w3svc/" & Index)
If (Err.Number = 0) Then
bDone = True
Else
Index = Index + 1
End If
End If
End If

If (Index > 10000) Then
WScript.Echo "看起來不能創建站點,正在創建的站點的序號為: "&Index&"." & VbCrlf & "取消創建本站點。"
Exit Function
End If
Wend

NewBindings = Array(0)
NewBindings(0) = BindingString
NewWebServer.ServerBindings = NewBindings
NewWebServer.ServerComment = ServerComment
NewWebServer.AnonymousUserName = AnonymousUserName
NewWebServer.AnonymousUserPass = AnonymousUserPass
NewWebServer.KeyType = "IIsWebServer"
NewWebServer.FrontPageWeb = True
NewWebServer.EnableDefaultDoc = True
NewWebServer.DefaultDoc = "Default.htm, Default.asp, Index.htm, Index.asp"
NewWebServer.LogFileDirectory = LogFileDirectory
NewWebServer.SetInfo

Set NewDir = NewWebServer.Create("IIsWebVirtualDir", "ROOT")
NewDir.Path = RootDirectory
NewDir.AccessRead = true
NewDir.AppFriendlyName = "應用程序" & ServerComment
NewDir.AppCreate True
NewDir.AccessScript = True
Err.Clear
NewDir.SetInfo
If (Err.Number = 0) Then
Else
WScript.Echo "主目錄創建時出錯."
End If

If Start = True Then
Err.Clear
Set NewWebServer = GetObject("IIS://" & Computer & "/w3svc/" & Index)
NewWebServer.Start
If Err.Number <> 0 Then
WScript.Echo "啟動站點時出錯!"
Err.Clear
Else
End If
End If
ASTCreateWebSite = Index
End Function

下面函數創建FTP站點:
Function ASTCreateFtpSite(IPAddress, RootDirectory, ServerComment, HostName, PortNum, Computer, Start,LogFileDirectory)
Dim MSFTPSVC, FtpServer, NewFtpServer, NewDir
Dim Bindings, BindingString, NewBindings, Index, SiteObj, bDone
On Error Resume Next
Err.Clear
Set MSFTPSVC = GetObject("IIS://" & Computer & "/MSFTPSVC")
If Err.Number <> 0 Then
WScript.Echo "無法打開: "&"IIS://" & Computer & "/MSFTPSVC" & VbCrlf & "程序將退出."
WScript.Quit (1)
End If

BindingString = IpAddress & ":" & PortNum & ":" & HostName
For Each FtpServer in MSFTPSVC
If FtpServer.Class="IIsFtpServer" Then
Bindings = FtpServer.ServerBindings
If BindingString = Bindings(0) Then
WScript.Echo "IP地址沖突:" & IpAddress & ",請檢測IP地址!." & VbCrlf & "取消創建本站點。"
Exit Function
End If
End If
Next

Index = 1
bDone = False

While (Not bDone)
Err.Clear
Set SiteObj = GetObject("IIS://"&Computer&"/MSFTPSVC/" & Index)
If (Err.Number = 0) Then
Index = Index + 1
Else
Err.Clear
Set NewFtpServer = MSFTPSVC.Create("IIsFtpServer", Index)
If (Err.Number <> 0) Then
Index = Index + 1
Else
Err.Clear
Set SiteObj = GetObject("IIS://"&Computer&"/MSFTPSVC/" & Index)
If (Err.Number = 0) Then
bDone = True
Else
Index = Index + 1
End If
End If
End If

If (Index > 10000) Then
WScript.Echo "看起來不能創建站點,正在創建的站點的序號為: "&Index&"." & VbCrlf & "取消創建本站點。"
Exit Function
End If
Wend

NewBindings = Array(0)
NewBindings(0) = BindingString
NewFtpServer.ServerBindings = NewBindings
NewFtpServer.ServerComment = ServerComment
NewFtpServer.AllowAnonymous = False
NewFtpServer.AccessWrite = True
NewFtpServer.AccessRead = True
NewFtpServer.DontLog = False
NewFtpServer.LogFileDirectory = LogFileDirectory
NewFtpServer.SetInfo

Set NewDir = NewFtpServer.Create("IIsFtpVirtualDir", "ROOT")
NewDir.Path = RootDirectory
NewDir.AccessRead = true
Err.Clear
NewDir.SetInfo
If (Err.Number = 0) Then
Else
WScript.Echo "主目錄創建時出錯."
End If

If Start = True Then
Err.Clear
Set NewFtpServer = GetObject("IIS://" & Computer & "/MSFTPSVC/" & Index)
NewFtpServer.Start
If Err.Number <> 0 Then
WScript.Echo "啟動站點時出錯!"
Err.Clear
Else
End If
End If
ASTCreateFtpSite = Index
End Function

注:如果您想引用上面的代碼,請與white聯系以取得技術支持.

北斗有巢氏 有巢氏北斗