嗨,Scripting Guy!

Hey,Scripting Guy!

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

今天的問題:如何判斷使用者帳戶的 SID?


如何判斷使用者帳戶的 SID?

嗨,Scripting Guy!如何判斷使用者帳戶的 SID?

-- MD

MD,您好。一看到縮寫字就傻眼的人 (我不是在責怪你們) 不妨瞭解一下,SID 就是安全識別項 (Security Identifier) 的縮寫而已。SID 是指定給網域中或本機電腦上所建立之每一個帳戶的唯一識別碼字串 (例如 S-1-5-21-1454471165-1004336348-1606980848-5555)。就我們的用途而言,我們可以說 SID 就是作業系統如何追蹤帳戶的方法。例如,您可以重新命名電腦上的「系統管理員」帳戶,卻仍然能用這個帳戶作為系統管理員的用途,因為 Windows 並不理會帳戶的名稱為何;不論帳戶名稱如何變,Windows 仍然知道這個帳戶是「系統管理員」帳戶,因為它的 SID 仍然保持不變。就像您的「身分證字號」一樣,只要您的身分沒有被別人冒用,不論您改過幾次名字,它都能辨別「您」。

在大部份情況下您幾乎都不需要處理 SID,這當然很省事。很顯然,處理像 kenmyer 這樣的帳戶名稱,肯定要比處理像 S-1-5-21-1454471165-1004336348-1606980848-5555 這樣的 SID 簡單多了。但是,總會有些時候您需要知道哪個 SID 屬於哪個使用者帳戶。例如,WMI 的安全性類別就必須依賴 SIDs;同樣地,Windows 登錄也會用 SID 追蹤使用者設定檔,而不是用名稱 (仔細看一下 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList 就明白我說的意思了)。或許在您撰寫指令碼的整個生涯階段中都不需要知道使用者的 SID,但是,總會有機會…

那麼,我們要如何尋找使用者的 SID 呢?嗯,我們可以用類似下面的指令碼,它會傳回使用者 kenmyerfabrikam 網域中帳戶的 SID:

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set objAccount = objWMIService.Get _
    ("Win32_UserAccount.Name='kenmyer',Domain='fabrikam'")
Wscript.Echo objAccount.SID

您可以看到,SID 實際上比指令碼還要長。我們在這裡做的動作,只是連線到 WMI 服務,然後用 Get 方法繫結到所指定 Win32_UserAccount 類別的執行個體。請留意,我們沒有使用 ExecQuery 傳回我們網域中所有 SIDs 的集合;這種方式行不通。我們必須使用 Get 並且指定一個特定的使用者帳戶。接下來就簡單了,只不過是回應 SID 而已;指令碼最後一行做的就是這個動作。

順便一提,這種方式對本機使用者帳戶也一樣適用。唯一的差異在於,您對 Domain 參數不是指定網域名稱,而是指定本機電腦的名稱。例如,下面的指令碼會傳回本機使用者帳戶 kenmyer 在電腦 atl-ws-01 上的 SID:

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set objAccount = objWMIService.Get _
    ("Win32_UserAccount.Name='kenmyer',Domain='atl-ws-01'")
Wscript.Echo objAccount.SID

很流暢吧?

當然,您也有可能必須處理另一種完全相反的方向;換句話說,您已經知道 SID,現在必須知道這個 SID 屬於哪個帳戶。我們可以做到這點嗎?當然可以!

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set objAccount = objWMIService.Get _
    ("Win32_SID.SID='S-1-5-21-1454471165-1004336348-1606980848-5555'")
Wscript.Echo objAccount.AccountName
Wscript.Echo objAccount.ReferencedDomainName

其中最大的差異在於,我們不用取得 Win32_UserAccount 類別的執行個體,而是要取得 Win32_SID 類別的執行個體 (請留意,我們傳遞 SID 作為給 Get 方法的參數)。擷取這個執行個體之後,我們只要回應帳戶名稱和網域名稱,就大功告成了!


如需詳細資訊

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

 

回到頁首 回到頁首