Share via


嗨,Scripting Guy!

Hey,Scripting Guy!

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

今天的問題:如何依據群組中的成員資格對應磁碟機?


如何依據群組中的成員資格對應磁碟機?

嗨,Scripting Guy!請問如何在登入指令碼中依據每個使用者所屬的安全性群組對應磁碟機?

-- RO

RO,您好。由於大概已經有 3,755,392 位讀者 (啊!還要加一位,現在是 3,755,393 位讀者) 詢問這個問題,所以我們決定最好還是回答一下。現在就為您說清楚,講明白。

這裡面其實有兩個問題。首先,您必須判斷使用者屬於哪一個群組;其次,您必須依據使用者在特定群組中的成員資格來對應磁碟機。因為這次要處理兩個問題,讓我們採取慣用的方法,先示範如何執行步驟 1,再示範如何執行步驟 2,然後再把它們聚在一起來個大團圓,實際執行我們所討論的工作。

首先,您必須判斷使用者屬於哪一個群組;不過,在您實際執行「這個動作」之前,您必須先判斷這位使用者是誰。由於您要執行的是登錄指令碼,所以這一點應該很簡單。您可以用 ADSystemInfo 物件判斷剛登入的使用者的辨別名稱:

Set objSysInfo = CreateObject("ADSystemInfo")
Wscript.Echo strUser.UserName

為什麼要用辨別名稱,而不用使用者的登入名稱呢?嗯...辨別名稱 (類似這樣 CN=Ken Myer、OU=Finance、DC=fabrikam 以及 DC=com) 可以告訴您接近完整的使用者 Active Directory 使用者帳戶的路徑;事實上,我們只需將 LDAP:// 加在它前面,就可以進行下面的動作了。像 kmyer 這樣的登入名稱並不是十分夠用;但是假如我們只有登入名稱,我們就必須進行一次 Active Directory 搜尋才能判斷這個帳戶的 ADsPath。一開始就用辨別名稱的話,可以讓我們省掉這些步驟。

加上 LDAP:// 建構好 ADsPath 之後,我們要繫結到 Active Directory 中的使用者帳戶,然後回報使用者所屬的群組;這個動作只需列舉 MemberOf 屬性中的值就可以完成。因此:

On Error Resume Next
Set objSysInfo = CreateObject("ADSystemInfo")
Set objNetwork = CreateObject("Wscript.Network")
strUserPath = "LDAP://" & objSysInfo.UserName
Set objUser = GetObject(strUserPath)
For Each strGroup in objUser.MemberOf
    strGroupPath = "LDAP://" & strGroup
    Set objGroup = GetObject(strGroupPath)
    Wscript.Echo objGroup.CN
Next

請注意,我們在這裡執行的動作,是用下面這行程式碼建構該群組的 ADsPath:

strGroupPath = "LDAP://" & strGroup

接下來再繫結到這個群組,並且傳回 CN 的值。為什麼?嗯...因為 MemberOf 屬性會傳回該使用者所屬的每一個群組的辨別名稱;因此,您可以取得像 CN=Finance Users、OU=Finance、DC=fabrikam 以及 DC=com 這樣的名稱。這一點應該沒問題,但是我們其實只需要像 Finance Users 這樣的群組名稱 (如 CN)。所以我們要繫結到這個群組,然後擷取 CN。

至於步驟 2,對應到網路磁碟機,那就更簡單了;下面的程式碼會將磁碟機 X 對應到共用 \\atl-fs-01\finance:

Set objNetwork = CreateObject("Wscript.Network")
objNetwork.MapNetworkDrive "X:", "\\atl-fs-01\finance"

我們只需要建立 WSH Network 物件的執行個體,再呼叫 MapNetworkDrive 方法,傳遞兩個參數給這個方法:磁碟機代號和我們所要對應的檔案共用。

再接下來,終於到大結局了!我們的指令碼要判斷使用者屬於哪個群組,再依據群組成員資格將磁碟機 X 對應到適當的網路共用。要執行這些,我們必須傳回所有群組的清單,然後用 Select Case 陳述式檢查使用者是否屬於其中一個目標群組。例如,下面的程式碼會檢查使用者是否屬於 Finance Users 群組;如果是,指令碼便會將磁碟機 X 對應到共用 \\atl-fs-01\finance:

Case "Finance Users"
        objNetwork.MapNetworkDrive "X:", "\\atl-fs-01\finance"

以下就是完成的指令碼:

On Error Resume Next
Set objSysInfo = CreateObject("ADSystemInfo")
Set objNetwork = CreateObject("Wscript.Network")
strUserPath = "LDAP://" & objSysInfo.UserName
Set objUser = GetObject(strUserPath)
For Each strGroup in objUser.MemberOf
    strGroupPath = "LDAP://" & strGroup
    Set objGroup = GetObject(strGroupPath)
    strGroupName = objGroup.CN
    Select Case strGroupName
        Case "Finance Users"
            objNetwork.MapNetworkDrive "X:", "\\atl-fs-01\finance"
        
        Case "Human Resource Users" 
            objNetwork.MapNetworkDrive "X:", "\\atl-fs-01\hr"
        Case "Manufacturing Users"
            objNetwork.MapNetworkDrive "X:", "\\atl-fs-01\manufacturing"
        Case "Shipping and Receiving Users"
            objNetwork.MapNetworkDrive "X:", "\\atl-fs-01\shipping"
    End Select
Next

這個指令碼有兩個必須注意的地方:第一,指令碼假設使用者只屬於前面所提的其中一個群組。假如某位使用者既屬於 Manufacturing Users 群組,又屬於 Shipping and Receiving Users 群組,在這種情況下,磁碟機 X 將會對應到 \\atl-fs-01\manufacturing,但是當指令碼嘗試將磁碟機 X 對應到 \\atl-fs-01\shipping 時便會發生錯誤,因為這部磁碟機已經在使用中。如果使用者有可能屬於多個群組,您必須事先考慮到這種情況,或許可以選擇允許多磁碟機對應 (例如,對應磁碟機 X,假如磁碟機 X 已經被使用了,就將下個群組的磁碟機對應到磁碟機 Y)。以後有機會我們再詳細討論這個部份。

其次,這個指令碼假設使用者都是依安全性群組中的名稱排列。但是,萬一使用者 Ken Myer 剛好是 Accounting 群組的成員,而這個「群組」(不是指個別使用者) 又是 Finance Users 的成員,那該怎麼辦?在這種情況下,磁碟機將無法正確對應,因為這個指令碼無法處理巢狀群組 (群組中的群組)。那是更複雜的指令碼,將來有機會再為大家示範。


如需詳細資訊

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

 

回到頁首 回到頁首