嗨,Scripting Guy!

Hey,Scripting Guy!

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

今天的問題:我是否能「只」從安全性事件記錄檔擷取失敗事件?


我是否能只從安全性事件記錄檔擷取失敗事件?

嗨,Scripting Guy!是否有方法能只從「安全性事件記錄檔」擷取「稽核失敗」事件?

-- KA

KA,您好。這還真是有趣:只要遭遇失敗,人們就會轉向 Scripting Guy 求助。您怎麼知道我們對失敗會有所瞭解的?

好的。您的想法很正確:我們的問題很蠢。就您的問題而言,想要只從「安全性事件記錄檔」擷取「安全性稽核失敗事件」是很容易的。事實上,我們手邊剛好就有能夠做到這點的指令碼:

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate,(Security)}!\\" & _
        strComputer & "\root\cimv2")
Set colLoggedEvents = objWMIService.ExecQuery _
    ("Select * FROM Win32_NTLogEvent WHERE Logfile = 'Security' " & _
        "AND EventType = 5")
For Each objEvent in colLoggedEvents
    Wscript.Echo "==================================================="
    Wscript.Echo "Category: " & objEvent.Category
    Wscript.Echo "Computer Name: " & objEvent.ComputerName
    Wscript.Echo "Event Code: " & objEvent.EventCode
    Wscript.Echo "Message: " & objEvent.Message
    Wscript.Echo "Record Number: " & objEvent.RecordNumber
    Wscript.Echo "Source Name: " & objEvent.SourceName
    Wscript.Echo "Time Written: " & objEvent.TimeWritten
    Wscript.Echo "Event Type: " & objEvent.Type
    Wscript.Echo "User: " & objEvent.User
    Wscript.Echo
Next

一段相當簡短的指令碼,不過您至少應該注意兩點。首先,請注意我們在連結到 WMI 時包含 (Security) 參數:

Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate,(Security)}!\\" & _
        strComputer & "\root\cimv2")

只要使用「安全性事件記錄檔」,您就必須包含這個參數。如果沒有包含這個參數,指令碼就會失去作用。而且,沒錯,我們「知道」您是本機系統管理員,也「瞭解」您擁有讀取「安全性記錄檔」的權限。可是不論如何,WMI 都不會因為這點而所不同:您依然需要包含 (Security) 參數。

其次,請注意 WHERE 子句中的兩個部分:

("Select * from Win32_NTLogEvent WHERE Logfile = 'Security' " & _
        "AND EventType = 5")

在這段指令碼中,我們只要擷取符合兩項條件的事件:它們記錄在「安全性事件記錄檔」中,而且 EventType 為 5。您可能已經明白,在 WMI 的語言裡,EventType 為 5 表示「稽核失敗」。另外,您也可以搜尋值分別等於 1 (錯誤)、2 (警告)、3 (資訊) 或 4 (安全性稽核成功) 的 EventType。由於我們需要「稽核失敗」事件,所以要尋找安全性「記錄檔案」中 EventType 為 5 的事件,因此:

WHERE Logfile = 'Security' AND EventType = 5

很棒吧?如果需要關於使用事件記錄檔的詳細資訊 (包括一些您可能覺得有用的範例查詢),請參閱《Microsoft Windows 2000 指令碼指南》中的記錄檔章節 (英文)。

既然您已經讀到這裡,我們最好補充一些重要事實。以這段指令碼目前的情況來看,它會顯示具有 WMI 的預設「國際標準時間」(UTC,Universal Time Coordinate) 格式的 TimeWritten 屬性 (也就是在事件記錄檔中記錄事件的日期和時間)。換句話說,您會得到類似以下的結果:

20041025124000.000000-420

真是 … 好呀 …!不過請不要絕望。以下是修改過的指令碼,其中含有一個函式 (WMIDateStringTodate),能將「國際標準時間」(UTC) 值轉換為容易閱讀的資訊:

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate,(Security)}!\\" & _
        strComputer & "\root\cimv2")
Set colLoggedEvents = objWMIService.ExecQuery _
    ("Select * FROM Win32_NTLogEvent WHERE Logfile = 'Security' " & _
        "AND EventType = 5")
For Each objEvent in colLoggedEvents
    Wscript.Echo "==================================================="
    Wscript.Echo "Category: " & objEvent.Category
    Wscript.Echo "Computer Name: " & objEvent.ComputerName
    Wscript.Echo "Event Code: " & objEvent.EventCode
    Wscript.Echo "Message: " & objEvent.Message
    Wscript.Echo "Record Number: " & objEvent.RecordNumber
    Wscript.Echo "Source Name: " & objEvent.SourceName
    dtmEventDate = objEvent.TimeWritten
    strTimeWritten = WMIDateStringToDate(dtmEventDate)
    Wscript.Echo "Time Written: " & strTimeWritten
    Wscript.Echo "Event Type: " & objEvent.Type
    Wscript.Echo "User: " & objEvent.User
    Wscript.Echo
Next
Function WMIDateStringToDate(dtmEventDate)
    WMIDateStringToDate = CDate(Mid(dtmEventDate, 5, 2) & "/" & _
        Mid(dtmEventDate, 7, 2) & "/" & Left(dtmEventDate, 4) _
            & " " & Mid (dtmEventDate, 9, 2) & ":" & _
                Mid(dtmEventDate, 11, 2) & ":" & Mid(dtmEventDate, _
                    13, 2))
End Function

今天我們不會解釋這段指令碼的作用,不過如果您有任何相關問題的話,請告訴我們。也許我們會在未來的專欄中進行深入的探討。


如需詳細資訊

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

 

回到頁首 回到頁首