Share via


嗨,Scripting Guy!

嗨,Scripting Guy!

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

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

今天的問題:如何判斷本機管理員群組的名稱呢?


如何判斷本機管理員群組的名稱呢?

嗨,Scripting Guy!如何判斷本機管理員群組的名稱呢?這要看作業系統的語言了,比如說德文系統的群組名稱是 Administratoren。

-- DS

DS,您好。聽到您的問題,我們第一個想到的就是找 Scripting Guy Peter Costantini,他會說好幾種人類語言 (還有好幾種人類語言)。能識別本機管理員群組名稱的人,非 Peter 莫屬。

但是這就牽涉到兩個問題,第一,我們沒法保證 Peter 隨時有空,他老是神龍不見尾。而且就算 Peter 會說好幾種語言,如果本機管理員群組已經重新命名,那他的語言能力也無用武之地,因為一旦更名,德文版 Windows 的本機管理員群組可能就不叫 Administratoren 了。而會隨著命名者決定。

我們決定要試試指令碼。下面的指令碼會傳回 Windows XP 或 Windows Server 2003 電腦上的本機管理員群組名稱 (稍後並為您介紹 Windows 2000 版本的作法):

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colAccounts = objWMIService.ExecQuery _
    ("Select * From Win32_Group Where LocalAccount = TRUE And SID = 'S-1-5-32-544'")
For Each objAccount in colAccounts
    Wscript.Echo objAccount.Name
Next

就是這麼簡單,只要有 WMI 指令碼就可以輕鬆搞定。我們先連接到本機電腦上的 WMI 服務,我們也可以連接到遠端電腦上的 WMI 服務,只要對 strComputer 變數指定遠端電腦的名稱即可。例如,這行程式碼可讓指令碼對連接到遠端電腦 atl-dc-01:

strComputer = "atl-fs-01"

接下來是這小段有趣的程式碼:

Set colAccounts = objWMIService.ExecQuery _
    ("Select * From Win32_Group Where LocalAccount = TRUE And SID = 'S-1-5-32-544'")

在這裡我們執行的動作是針對符合下列條件電腦上的群組發出 WMI 查詢:

  • LocalAccount 屬性的值為 True。這是查詢中很重要的一個部分,因為它限制 WMI 只能查詢本機帳戶,如果沒有設定,那麼 WMI 會查詢 Active Directory 裡每一個群組。
  • SID 屬性的值為 S-1-5-32-544。SID (安全識別碼) 是一組獨一無二的號碼,可供作業系統識別帳戶。因此您可以變更本機管理員帳戶的名稱,無須擔心本機管理員就此無法進行存取。大部分的情況下,作業系統會採 SID 而忽略使用帳戶名稱。而且這個值永遠都不會更改。

所以說 S-1-5-32-544 值相當重要囉?沒錯,這個 SID 號碼碰巧「很出名」,而且永遠參考本機管理員群組。也就是說,如果您找到的本機帳號 SID 為 S-1-5-32-544,賓果!您就找到了本機管理員群組。就是這麼簡單!

剩下來的指令碼很簡單,只要設定一個 For Each 迴圈,以 SID S-1-5-32-544 跑過所有的本機群組並傳回每個群組的名稱即可。由於每台電腦上的 SID 都不一樣,而且 S-1-5-32-544 指的一定是本機管理員群組,您蒐集到的結果正是本機管理員群組,僅此一個,別無他物。這樣一來,不管您的作業系統採用何種語言,不管您的本機管理員群組名稱為何,都找得到。

但是這個指令碼的確有其缺陷,前面曾說過,它只適用 Windows XP 和 Windows Server 2003。Windows 2000 的使用者別擔心,咱們可沒忘了您。下面是改寫過的指令碼,適用 Windows 2000、Windows XP、Windows Server 2003,甚至 Windows NT 4.0:

strComputer = "atl-fs-01"
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colAccounts = objWMIService.ExecQuery _
    ("Select * From Win32_Group Where Domain = '" & strComputer & "' AND SID = 'S-1-5-32-544'")
For Each objAccount in colAccounts
    Wscript.Echo objAccount.Name
Next

原先的指令碼不適用 Windows 2000,因為在 Windows XP 推出前,Win32_Group 類別不支援 LocalAccount 屬性。因此,我們在指令碼稍微改了兩處:

  • 我們以名稱連結至本機電腦 (而非使用 WMI 的本機電腦縮寫,也就是一個英文句點)。
  • 查詢中尋找的對象不是將 LocalAccount 設定為 True 的群組,因為不支援 LocalAccount 屬性,我們要找 Domain 屬性的值等於本機電腦名稱的群組,因為這些是本機帳戶 (想必讀者已經猜到了)。

如果您也像 Peter 一樣,總在意想不到的時間與空間穿梭,說不定碰巧遇到可以請他判斷本機管理員名稱,不然用今天介紹的指令碼當作 B 計畫也不錯喔。


如需詳細資訊

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

 

回到頁首 回到頁首