嗨,Scripting Guy!
本文內容
歡迎使用 TechNet 專欄,Microsoft Scripting Guy 會在此為您解答有關系統管理指令碼的常見問題。您有關於系統管理指令碼方面的問題嗎?請將電子郵件傳送到 scripter@microsoft.com 。我們無法保證能夠逐一回答每個問題,不過我們會盡力而為。
還有,別忘了瞧瞧全新經過改良的《嗨,Scripting Guy!過往文件 》。
今天的問題:如何監視登錄機碼的變更呢?
如何監視登錄機碼的變更呢?
問
嗨,Scripting Guy! 我可以使用指令碼來監視登錄機碼的變更嗎?我希望只要有人變更 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run 機碼,就隨時通知我。
-- SB
答
SB,您好。謝謝您費心描述問題:若要隨時接獲有人更改機碼的通知,其實很容易。不過如果您繼續問:「能不能也順便告訴我,是誰變更機碼,他又做了哪些變更?」,這就有點困難了 (容我待會兒為您解釋)。既然您沒有繼續問,就當我沒說吧。
我們先看看監視 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run 登錄機碼的指令碼,然後在機碼變更時回應訊息:
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\default")
Set colEvents = objWMIService.ExecNotificationQuery _
("SELECT * FROM RegistryKeyChangeEvent WHERE Hive='HKEY_LOCAL_MACHINE' AND " & _
"KeyPath='SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run'")
Do
Set objLatestEvent = colEvents.NextEvent
Wscript.Echo Now & ": The registry has been modified."
Loop
我們先連接到 WMI 服務。說得更明確一點,就是連接到 root\default 命名空間,也就是登錄事件類別所在的地方。接著再使用 ExecNotificationQuery 方法,發出下述查詢:
("SELECT * FROM RegistryKeyChangeEvent WHERE Hive='HKEY_LOCAL_MACHINE' AND " & _
"KeyPath='SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run'")
您只需要求 RegistryKeyChangeEvent 類別一建立執行個體,就發出通知。因為正如您所猜測,只要指定的登錄機碼一變更 (例如,加入新值,或是修改或刪除現有的值),這個類別就會建立一個執行個體。
聽起來很不錯,不過我們該如何指定登錄機碼呢?很簡單,只要設定 RegistryKeyChangeEvent 類別的下列兩個屬性就好:
Hive 。這是機碼所在的登錄 Hive (位置)。我們希望監視位於 HKEY_LOCAL_MACHINE 的機碼,因此把 Hive 屬性的值設為 HKEY_LOCAL_MACHINE。如果我們希望監視位於 HKEY_CURRENT_USER 的登錄機碼,就設為 HKEY_CURRENT_USER。請注意,在設定 Hive 屬性時,不必定義和使用常數,只要輸入登錄 Hive 的實際名稱即可。
KeyPath 。這是 Hive 裡面的路徑,通往我們的登錄機碼。由於 \ 是 WMI 的一個保留字元,必須在每一個 \ 另外加上第二個 \ 才行。因此,如果機碼路徑是 Software\Microsoft\Windows\CurrentVersion\Run,就必須改寫為 Software\\Microsoft\\Windows\\CurrentVersion\\Run。
發出查詢之後,我們再設定一個 Do 迴圈,讓它永遠執行,盡責的等候 RegistryKeyChangeEvent 類別的下一個執個體出現。我們可以利用下面這行程式碼,讓指令碼等候執行個體出現:
Set objLatestEvent = colEvents.NextEvent
這行程式碼會把指令碼「封鎖」起來,也就是說,指令碼只會在原地等候下一個事件發生 (如您所知,我們所監視的事件,就是 RegistryKeyChangeEvent 類別的執行個體)。當這類事件真的 發生時,我們只要回應目前的日期和時間,以及登錄被修改的事實即可。接著就重演歷史,等候下一個 事件發生。(如果要跳出迴圈,結束指令碼,請按 Ctrl+C)。
既然如此,為什麼我們不乾脆做得更徹底一點,而不只是注意登錄已被修改呢?那是因為我們不能 這麼做:諸如變更什麼,以及由誰變更這種細節,並不是由登錄事件提供者擷取。我們可以擷取登錄機碼的初始狀態,等事件發生時,再比較新狀態和初始狀態,藉此判斷一部份的資訊。接著就必須設定程序,讓我們繼續比較登錄機碼的最新狀態與前一個狀態。但是這個就得交由您自己負責了。(當然嘍,如果有其他狀況發生,那就另當別論。畢竟我們還是得信守服務的承諾嘛!)
如需詳細資訊
請參閱嗨,Scripting Guy!- 過往文件
回到頁首