Share via


嗨,Scripting Guy!

嗨,Scripting Guy!

歡迎使用《TechNet 專欄》,Microsoft Scripting Guys 會在此為您解答有關系統管理指令碼的常見問題。您有關於系統管理指令碼方面的問題嗎?請將電子郵件傳送到 scripter@microsoft.com。我們無法保證能夠逐一回答每個問題,不過我們會盡力而為。

還有,別忘了瞧瞧全新經過改良的嗨,Scripting Guy!過往文件

今天的問題:如何將電腦從未知的 OU 移至已知的 OU?


如何將電腦從未知的 OU 移至已知的 OU?

嗨,Scripting Guy!如何將電腦從未知的 OU 移至已知的 OU?

-- DB

DB,您好。多數人對系統管理指令碼的看法是「有用但稍嫌枯燥」。清除事件日誌和變更使用者密碼雖然有其功能,但是比起「最後一戰 2」或「神話世紀」就顯得失色許多。

啊,您描述情況顯然有趣多了。有幾台電腦叛逃到未知 OU,您的任務是追蹤這些電腦,將它們帶回已知 OU。這樣才像話,「星際爭霸 2」也不見得這麼刺激!

最棒的是 Scripting Guy 還可以趁機擺脫 Script Center,改為更響亮的系統管理程式碼偷吃步中心。我們也不再需要處理老掉牙的無聊指令碼,轉而討論真正有趣的程式碼撇步,研究怎麼幫您遊戲破關。像是這樣的偷吃步:

On Error Resume Next
Const ADS_SCOPE_SUBTREE = 2
objOU = GetObject("LDAP://ou=Finance,dc=fabrikam,dc=com")
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand =   CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection
objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE 
objCommand.CommandText = _
    "SELECT ADsPath FROM 'LDAP://dc=fabrikam,dc=com' WHERE objectCategory='computer' " & _
        "AND Name='atl-ws-01'"
Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst
Do Until objRecordSet.EOF
    strADsPath = objRecordSet.Fields("ADsPath").Value
    objOU.MoveHere strADsPath, vbNullString
    objRecordSet.MoveNext
Loop

TechNet Script Center

上面的指令碼... 偷吃步,主要用於搜尋 Active Directory。這麼寫是有原因的,這就是追蹤 OU 內任何電腦的策略。您在電子郵件中提到已經知道電腦名稱,但就是不知道它在 Active Directory 中的位置。沒問題,只要用指定名稱搜尋電腦,擷取出位置 (技術上來說,就是 ADsPath),就可以從這裡起步。

怎樣,很簡單吧!像是最棒的電玩「蟲蟲入侵」,或是史上最強的電玩「Burger Time」都是以簡單為精髓。

先建立一個名為 ADS_SCOPE_SUBTREE 的常數,值設為 2。用這個常數告訴指令碼我們要搜尋整個 Active Directory,包括所有的 OU 和子 OU。接著使用這行程式碼建立一個 Finance OU 的物件參考,也就是希望移動電腦的「已知」OU:

objOU = GetObject("LDAP://ou=Finance,dc=fabrikam,dc=com")

懂了嗎?接下來透過一大段程式碼進行設定並執行搜尋。至於 Active Directory 搜尋的原理和來龍去脈已經超出這篇小專欄的篇幅,依慣例不會深入說明。如需其他資訊,請參閱雙部曲指令碼物語系列中的<老兄,我的列表機咧? (英文)> (Dude, Where's My Printer?)。現在把討論重點放在搜尋內使用的查詢:

objCommand.CommandText = _
    "SELECT ADsPath FROM 'LDAP://dc=fabrikam,dc=com' WHERE objectCategory='computer' " & _
        "AND Name='atl-ws-01'"

這個程式碼的主要目的是針對任何 Name 等於 atl-ws-01 的電腦,擷取其 ADsPath (objectCategory = 'computer')。接著呼叫 Execute 方法,由指令碼搜尋 Active Directory 並傳回具有指定 Name 的電腦集合。(由於 Name 必須是獨一無二的,集合中最多只會有一個項目。)

問得好:為什麼要擷取 ADsPath 屬性呢?ADsPath 屬性有點類似 UNC 路徑,可提供確切的「地址」,方便找出指定的物件。例如 atl-ws-01 的 ADsPath 可能就像:

LDAP://cn=atl-ws-01,ou=Research,dc=fabrikam,dc=com

還記得我們說過這台電腦位置不明嗎?這已經不再是問題囉,現在我們已經掌握到它的位置,也知道怎麼前往。

這不過表示我們已經破了第一關,還有第二關「把電腦移至 Finance OU」要破。方法是使用下面這段程式碼:

Do Until objRecordSet.EOF
    strADsPath = objRecordSet.Fields("ADsPath").Value
    objOU.MoveHere strADsPath, vbNullString
    objRecordSet.MoveNext
Loop

這裡設定了一個 Do Until 迴圈,會一直執行到抵達資料錄集 (objRecordSet.EOF) 的末端。在迴圈內使用這一行程式碼取得 ADsPath 路徑,並將路徑儲存在名為 strADsPath 的變數中:

strADsPath = objRecordSet.Fields("ADsPath").Value

現在準備好移動電腦囉,方法可真簡單:

objOU.MoveHere strADsPath, vbNullString

我們用 Finance OU 的物件參考 (objOU) 並呼叫 MoveHere 方法。MoveHere 需要兩個參數:

  • strADsPath:這是個變數,包含 atl-ws-01 電腦的 ADsPath (位置)。
  • vbNullString:這是一個 VBScript 常數,用來代表 Null 變數。藉著指定不同的 CN,您可以使用 MoveHere 方法的第二個參數將電腦重新命名,而不是移動電腦。我們只需要移動這個東西 (仍保留舊名),所以傳出 Null 變數作為第二個參數。

這樣就差不多了,接下來呼叫 MoveNext 方法,移至集合裡的第二筆記錄。因為不會有下一筆記錄,EOF 等於 True,就會跳出迴圈而結束指令碼。

附註:別漏了 MoveNext 方法,否則指令碼會被困在永無止境的迴圈裡,因為這種情況下指令碼會先移往集合中的第一個電腦,但尚未前往下一筆記錄,而會在第二次移動第一部電腦,然後又試第三次、第四次...


DB,這樣您手中就有一個全新的酷炫電玩,搜出遺失的電腦並送往不同的 OU。是啦,看起來沒什麼,但撇開懷舊不談,這不是比「太空侵略者」刺激多了嗎?


如需詳細資訊

查看嗨,Scripting Guy!- 過往文件

 

回到頁首 回到頁首