你曾經相通過VBS添加一個虛擬目錄嗎?(我想過~)自動建立ISAPI服務器擴展?或者建立一整個站點, 包括權限?你可以用ADSI做這些和更多的事情.
ADSI (Active Directory Services Interface)是一種應用程序數據接口.微軟的操作系統支持ADS I的有Windows NT 4.0 Server, Exchange, IIS, 和Site Server.在WIN2K中ADSI將會成為操作系統 的接口并且可能取代注冊表.ADSI的關鍵并不在于底層的數據存儲,而在于它自已的接口層.用一個 接口,只要學習一次,你就可以配置所有的服務器程序.(是不是很爽啊,呵呵!)不像API,你可以使用 所有的語言或環境來通過COM訪問ADSI.(這是后話!)
警告: 在運行本文章的例子之前,請先備份IIS4.0: 打開MMC (以下略去備份過程)
面向對象的數據庫
ADSI對所有的數據都當作對象來看待.用ADSI你可以熟練地操作所有的數據而不用去學一種數據庫 查詢語言如SQL.相對于一個關系型的數據庫,建立一個面向對象的數據庫要簡單和快速一些.在一個 關系數據庫中程序員不得不要知道一個對象是如何破壞和存儲的;然而面向對象的數據存儲,像ADSI ,不存在這些問題.程序員只要知道你想要訪問的那個對象的名字.
為了去對比這兩種數據庫類型,設想你要一個員工的資料:個人信息,部門信息,和薪水信息.在一個 關系數據庫中,這三個數據可能會被分別放在三個表中.而且對數據庫的一個更改可能只會影響到其 中的一部分表,對數據庫的修改程序員不得不通過一種數據庫查詢語言如SQL.很少用人去注意對象 是如何被存儲的(除了數據庫管理員).然而ADSI把所有的信息視為對象,對象之間的聯系正是ADSI執 行的一部分,因此,這一部分就不再需要程序員處理了.一旦你學會了處理一種ADSI數據,你就學會了 處理所有的ADSI數據庫.作為一個對比,你可能需要學習每一種關系數據庫語言如果你要用不同的數 據庫的話.(像FOXPRO)
數據結構
數據庫結構是一個分級的模型.一個對象節點可以是另一個節點的父節點,兄弟結點,或者一個子節 點.每一個子節點繼承父節點的屬性.數據庫有兩個邏輯部分.第一個是定義數據和數據關聯的計劃. 第二個部分是數據的實際存儲.定義一個員工對象是放在計劃部分,個人信息放在數據部分.
獲得一個對象的實例
不像COM,你不用去使用SERVER.CREATEOBJECT去獲得一個ADSI對象的實例.你只需使用GETOBJECT方 法和一個指定服務器和聯接位置的參數.例子一有兩個GETOBJECT的例子.在第一種情況下,代碼建立 了一個WINDOWS NT的ADSI實例.每二個例子取得了一個IIS的ADSI對象. Example 1
For Windows NT
Set Object = GetObject("WinNT://15seconds" )
For LDAP
Set Object = GetObject("IIS://localhost/w3svc/1")
一些AD服務接口用一種特別的被稱為X.500華貴名稱的命名規則.IIS并沒有用這種規則但是你必須 對X.500這一個命名規則因為你有可能還要操作其它的ADSI數據.你可以 從ftp://src.doc.ic.ac.uk/rfc/rfc1484.txt 得到相關資料.
數據取回
當我們在一個LDAP服務器上尋找信息時,我們必須知道是否信息在實例中或者在規劃部分.舉一個例 子來說,一個對象名稱可以包含在一個對象實例中但是一個對象屬性的列表將會存儲在一個計劃部 分.員工名稱,雇傭日期,和部門被存儲在員工對象中.計劃部分存儲了員工屬性的定義像數據類型. 例二說明了一個對象實例和對象計劃的定義. Example 2
Employee Instance Name: Bob Jones Hire Date: 1/1/98 Department: Information Technology
Employee Object Instance Attribute "Name", single value, data-type "text", maxlength 50" Attribute "Hire Date", single value, data-type "date" Attribute "Department", single value, data-type "text"
對SQL程序員來說,對象定義和一個表的定義是相似的.對象實例就像是一個表中的特定的一行.SQL 和ADSI的區別就在于數據是不是跨越了多個表,程序員是否需要管理數據之間的關系.在ADSI中,接 口是這些關系的負責人.
默認WEB站點的通有屬性 第一個例子可以看到IIS4.0的默認WEB站點的屬性.在例3中,代碼會聯接到本地機的默認WEB站點. Example 3
<% strMachineName = "localhost" 'domain name strObjectPath = "W3SVC/1" 'object name
'construct object location in IIS strPath = "IIS://" & strMachineName & "/" & strObjectPath Set IISObject = GetObject (strPath) 'connect to IIS metabase %> Name = "<%= IISObject.Name %>"
Parent= "<%= IISObject.Parent %>"
SchemaLocation = "<%= IISObject.Schema %>"
Class = "<%= IISObject.Class %>"
Guid = "<%= IISObject.Guid %>"
ADSPath = "<%= IISObject.AdsPath %>"
輸出顯示是:
Name = "1" Parent= "IIS://localhost/W3SVC" SchemaLocation = "IIS://localhost/schema/IIsWebServer" Class = "IIsWebServer" Guid = "{8B645280-7BA4-11CF-B03D-00AA006E0975}" ADSPath = "IIS://localhost/W3SVC/1"
注意:如果你要在一個ASP頁面中運行本程序,請確定登陸的用戶被授予了管理員的權限.
在最后一個例子的數據取回可以用于任何一個對象,包括計劃對象.每一個對象不管他是一個實在的 對象還是一個計劃對象都肯定有這些屬性:名稱,父,計劃定們,CLASS,GUID,和ADS路徑.
這些信息包括了通過分級結構訪問數據的一些導航信息.NAME屬性是一個對象的名稱.一個parent屬 性告訴了父對象的位置.schemalocation屬性指的是計劃對象的位置.class屬性包括了對象的類型, 它包括了一個對象所有的屬性并且被定們到schemalocation這個位置.GUID屬性是一個對象的唯一 的識別碼.ADSPath是你取回的這個對象的位置.
注:名為1的服務器代表默認的WEB站點
默認WEB站點的屬性 既然我們已經知道了對象的位置和對象的類型,那就讓我們來看一看默認WEB站點的屬性.為了達到 這個目的,我們必須要取得默認WEB站點的計劃(schema),找出相關的屬性,并且看默認WEB站點的這 些屬性的值. Example 4
<% strMachineName = "localhost" strObjectPath = "W3SVC/1" 'find first web server listed in w3svc strPath = "IIS://" & strMachineName & "/" & strObjectPath Set IISObject = GetObject (strPath)
'find location of web server's definition Set ClassDefinition = GetObject(IISObject.Schema) %> <table border=1> <tr><th>Default Web Server Property</th><th>Default Web Server Value</th></tr> <tr><td>Name</td><td><%= IISObject.Name %></td></tr> <tr><td>Parent</td><td><%= IISObject.Parent %></td></tr> <tr><td>SchemaLocation</td><td><%= IISObject.Schema %></td></tr> <tr><td>Class</td><td><%= IISObject.Class %></td></tr> <tr><td>Guid</td><td><%= IISObject.Guid %></td></tr> <tr><td>ADSPath</td><td><%= IISObject.AdsPath %></td></tr>
<table border=1> <tr><th>Class Property</th><th>Class Value</th></tr> <tr><td>Name</td><td><%= ClassDefinition.Name %></td></tr> <tr><td>Parent</td><td><%= ClassDefinition.Parent %></td></tr> <tr><td>SchemaLocation</td><td><%= ClassDefinition.Schema %></td></tr> <tr><td>Class</td><td><%= ClassDefinition.Class %></td></tr> <tr><td>Guid</td><td><%= ClassDefinition.Guid %></td></tr> <tr><td>ADSPath</td><td><%= ClassDefinition.AdsPath %></td></tr>
<% on error resume next
asMustHaves = ClassDefinition.MandatoryProperties asMayHaves = ClassDefinition.OptionalProperties
i=1 %> <table border=1> <tr><th>Class Must Have Property</th> <th>Default Web Site Current Value</th></tr> <% For Each Thing in asMustHaves Response.Write "<tr><td>("& Cstr(i) & ") " &_ Thing & "</td><td>" &_ IISObject.Get(Thing) & "</td></tr>" i = i + 1 Next %>
<table border=1> <tr><th>Class May Have Property</th> <th>Default Web Site Current Value</th></tr> <% i=1 For Each Thing in asMayHaves Response.Write "<tr><td>("& CStr(i) & ") " &_ Thing & "</td><td>" &_ IISObject.Get(Thing) & "</td></tr>" i = i + 1 Next %>
為了取得默認WEB站點的屬性,你需要知道屬性的名稱,或者 isWebServer這一類的屬性的列表.在例 4中,我們取得了所有的屬性并且列出了他們的值.每個對象都可以有強制的和自已的屬性.強制的屬 性在每個對象建立時就產生了.
注意:如果IISWEBSERVER只列出了一些可選的屬性,在參考IIS文檔之前請不要建立一個新的WEB站 點的對象。ADSI對IIS的執行打破了這個規則。有一些必須的屬性列在了可選的屬性列表中。如果 你在建立一個WEB站點時沒有對必要的屬性進行設置,你的元數據庫可能被破壞。
注意:ADSI不會在錯誤時停下了,它會繼續前進。
建立一個虛擬目錄
在例五中我們將在默認的WEB站點下建立一個虛擬目錄。我們將先列出一個虛擬目錄的所有屬性然 后再建立一個虛擬目錄。為了列出一個目錄的所有屬性,我借用了例3的一些代碼,只不過將站點 改成了虛擬目錄,你必須知道必須的屬性:我們要建立怎樣的WEB服務器,它的名字,它的物理路 徑,一旦你建立了一個虛擬目錄后你再將它們的屬性一一設置。例五講了怎樣利用這些。 Example 5
<% sComputer ="localhost" sPhyDir = "c:\adsi" sVirDir = "ADSITest"
'Get Default Web Site Object set websvc = GetObject("IIS://" & sComputer & "/W3svc/1")
'Verify by printing out ServerComment Response.Write "Comment = " & websvc.ServerComment & " "
'Get root of Default Web Site set vRoot = websvc.GetObject("IIsWebVirtualDir", "Root")
'Get Class Definition of virtual directory Set ClassDefinition = GetObject(vRoot.Schema)
'Get list of mandatory properties asMustHaves = ClassDefinition.MandatoryProperties
'Get list of optional properties asMayHaves = ClassDefinition.OptionalProperties
i=1 %> <table border=1> <tr><th>Class Must Have Property</th> <th>Root Virtual Directory Current Value</th></tr> <% on error resume next
For Each Thing in asMustHaves Response.Write "<tr><td>("& Cstr(i) & ") " &_ Thing & "</td><td>" & vRoot.Get(Thing) &_ "</td></tr>" i = i + 1 Next %>
<table border=1> <tr><th>Class May Have Property</th> <th>Default Web Site Current Value</th></tr> <% i=1 For Each Thing in asMayHaves Response.Write "<tr><td>("& CStr(i) & ") " &_ Thing & "</td><td>" & vRoot.Get(Thing) &_ "</td></tr>" i = i + 1 Next on error goto 0
'Create Virtual Directory 'Param 1 is class name 'Param 2 is the new object name Set vDir = vRoot.Create("IIsWebVirtualDir",sVirDir)
'Only setting two properties vDir.AccessRead = true vDir.Path = sPhyDir
'Write information back to Metabase vDir.SetInfo %>
在這個例子中,為了建立一個對象的實例,父對象被用到了。建立對像的實例用的是對象的class 名稱。而這個對象沒有強制的屬性,一些對象有強制的屬性。如果你沒有設置這些必要的屬性,當 你使用object.setinfo時就會出錯。 為了檢驗這個虛擬目錄是否已經建立了,你可以打開IIS看一下。另一個方法是再運行一遍程序, 如果上次已經建立了,你這次就會得到錯誤結果。(推薦前一種,SUNWEN)
別一個ADSI的特征是在OBJECT。SETINFO被運行之前,所有的屬性設置都不會生效。這使你的站點 不會受一些非正規的影響(如果一個人正在請求這個站點的話,就會出現錯誤)。這比一個關系型 的數據庫更加簡單。ADSI會自動完成所有相關的數據的設置,你就可以不用使用N次的INSERT語句 (嘻嘻,老外和SUNWEN一樣幽默!)。更新也一樣。你只需一次則可。
加入一個默認的文檔
在這個例子中,我們將把"index.htm"這個文件加入到默認文檔的列表中。為了實現這一目標,我 們要從數據源中得到這個虛擬目錄,改變與默認文檔相關的屬性,然后把信息寫回去。 Example 6
<% sComputer ="localhost" sPhyDir = "c:\dina\adsi" sVirDir = "ADSITest"
'Get Default Web Site Object set websvc = GetObject("IIS://" & sComputer & "/W3svc/1")
'Verify by printing out ServerComment Response.Write "Comment = " & websvc.ServerComment & " "
'Get root of Default Web Site set vRoot = websvc.GetObject("IIsWebVirtualDir", "Root")
'Create Virtual Directory Set vDir = vRoot.Create("IIsWebVirtualDir",sVirDir)
'Get local copy of object vDir.GetInfo
Response.Write "Old Default Docs = " & vDir.DefaultDoc & "<BR>"
'Only setting two properties vDir.DefaultDoc = vDir.DefaultDoc & ",index.htm"
'Write information back to Metabase vDir.SetInfo
'Get Object Again vDir.GetInfo
Response.Write "New Default Docs = " & vDir.DefaultDoc %>
在這個例子中,我們是用了objec.getinfo這個語句把信息取回的。它一次性把所有的信息都取回 了。然后我們用setinfo這個語句把信息重新設置了回去。
刪除一個虛擬目錄
在這個例子中,你將學習到如何刪除一個虛擬目錄。當建立一個對象時,你必須有它的父對象。這 個真理也同樣適用于刪除。例七表明了如何做。 Example 7
<% on error resume next
sComputer ="localhost" sPhyDir = "c:\dina\adsi" sVirDir = "ADSITest"
'Get Default Web Site Object set websvc = GetObject("IIS://" & sComputer & "/W3svc/1")
'Verify by printing out ServerComment Response.Write "Comment = " & websvc.ServerComment & " "
'Get root of Default Web Site set vRoot = websvc.GetObject("IIsWebVirtualDir", "Root")
'Delete Virtual Directory Set vDir = vRoot.Delete("IIsWebVirtualDir",sVirDir) %>
|