嗨,Scripting Guy!

Hey,Scripting Guy!

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

今天的問題:我要如何判斷使用者帳戶的所屬組織單位?


我要如何判斷使用者帳戶的所屬組織單位?

嗨,Scripting Guy!我要如何判斷使用者帳戶的所屬組織單位?

-- CO

CO,您好。喔,是的:使用者所屬的組織單位。您們之中很多人一定在想:「好吧,在 Active Directory 應該有某種 OU (組織單位) 之類的屬性能夠提供您這項資訊。只要找到使用者帳戶,然後取得 OU 屬性的值就可以了。」

這樣聽起很有道理,不過您可能已經猜到,事情不是這樣作用的。事實的真相是,Active Directory 中並沒有 OU 屬性 (或任何對等用法的屬性)。不過請別煩惱。這並不表示我們無法判斷使用者的組織單位;只是我們 – 呼!必須要多費點兒功夫才能辦到。

就本專欄的目的,我們假設您不知道使用者的辨別名稱;畢竟,如果具有如 CN=kenmyer,OU=Finance,DC-fabrikam,DC=com 的辨別名稱,即使一般的 Scripting Guy (指令碼編寫者) 都能明白使用者所屬的組織單位。所以我們假定您只知道使用者的 SAM 帳戶名稱,也就是使用者通常用來登入網域的名稱。

如果「確實」知道 SAM 帳戶名稱,您就走運了。因為這些名稱在 Active Directory 樹系中必須是唯一的。因此,我們可以用 Active Directory 搜尋找到這名使用者:

n Error Resume Next
Const ADS_SCOPE_SUBTREE = 2
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 distinguishedName FROM 'LDAP://dc=fabrikam,dc=com' _
    WHERE objectCategory='user' " & _
        "AND sAMAccountName='kenmyer'"
Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst
Do Until objRecordSet.EOF
    Wscript.Echo objRecordSet.Fields("distinguishedName").Value
    objRecordSet.MoveNext
Loop

就像我們以前說明過的,儘管這段指令碼並不會太長或過於複雜,執行 Active Directory 搜尋所牽涉到的事項還是很多。如需詳細資訊,請參閱 Scripting Guy 的網路廣播 (英文)。

我們不對任何細節深入討論,在此要執行的是對 fabrikam.com 搜尋 sAMAccountName 為 kenmyer 的使用者。在找到這名使用者以後,我們會立即傳回他的辨別名稱 (distinguishedName 屬性)。由於辨別名稱具有 CN=kenmyer,OU=Finance,DC=fabrikam,DC=com 的形式,我們可以查看結果並判斷使用者的組織單位。

不過說實話,我們也懶得查看使用者的辨別名稱;所以要利用指令碼來完成這點。所以讓我們對指令碼的 Do 迴圈進行些微的修改。以下是修改過的程式碼,我們將在稍後解釋其中的作用。

CN=kenmyer 
OU=Finance
DC=fabrikam
DC=com

我們知道陣列中的第二個元素 (陣列中的第二個元素一定會具有 1 的索引號碼),就是使用者帳戶所屬的組織單位。這就表示,如果要得到組織單位的名稱,我們只需要取得第二個元素 (arrPath(1)),然後去掉 OU= 的部分。

我們可以做到這點嗎?當然可以。我們可以使用 Len 函式來判斷陣列中元素 0 的字元數目。請記得,該元素的值為 OU=Finance,所以字元的數目是 10。

接著我們從字元數目減去 3。為什麼?這是因為我們要去除 OU= 的部分,而 OU= 共有 3 個字元。從 10 減掉 3 就剩下 7,這就表示組織單位的實際名稱 – Finance – 具有 7 個字元的長度。

現在,我們最後使用 Right 函式抓取字串中的最後 7 個字元。我們從 OU=Finance 中的 e 開始,並且移回 7 個字元。您猜結果如何?您猜對了:OU=Finance 中的最後 7 個字元是 Finance,也就是使用者帳戶所屬的組織單位名稱。耶,我們辦到了!

以下是修訂過的指令碼,能夠搜尋 Active Directory 並回報使用者帳戶所屬的組織單位。

Const ADS_SCOPE_SUBTREE = 2
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 distinguishedName FROM 'LDAP://dc=fabrikam,dc=com' “ & _
        "WHERE objectCategory='user' " & _
            "AND sAMAccountName='kenmyer'"
Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst
Do Until objRecordSet.EOF
    strDN = objRecordSet.Fields("distinguishedName").Value
    arrPath = Split(strDN, ",")
    intLength = Len(arrPath(1))
    intNameLength = intLength - 3
    Wscript.Echo Right(arrPath(1), intNameLength)
    objRecordSet.MoveNext
Loop

如需詳細資訊

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

 

回到頁首 回到頁首