捐血一袋救人一命

2012年2月6日 星期一

匯出事件檢視器記錄到 .csv 檔案

最近又抽了點空,把以前匯出 Exchange POP3 Log 的程式改寫了一下,企圖讓這個程式能夠適用更多環境

為了方便操作起見,改成 HTML Application 介面,程式介面如下圖:

2012-02-06_143638

新的程式增加了一個選項,如果不分日期,一律匯出,就可以勾選「不要輸入日期」

程式碼如下:

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=big5" />
<title>Dump Event to CSV File</title>

<HTA:APPLICATION
     ID="objHTAHelpomatic"
     APPLICATIONNAME="HTADumpEvent"
     SCROLL="No"
     SINGLEINSTANCE="yes"
     BORDER="thick"
     BORDERSTYLE="raised"
     MAXIMIZEBUTTON="no"
     SHOWINTASKBAR="yes"
     WINDOWSTATE="normal"
>

</head>

<SCRIPT Language="VBScript">
' Setup Window Size
Sub Window_onLoad
    ' 設定視窗寬度
    Const Width = 480
    ' 設定視窗高度
    Const Height = 350
    ' 調整視窗大小
    self.ResizeTo width,height
    ' 移動視窗位置至螢幕畫面正中央
    Self.moveTo (screen.AvailWidth-width)/2,(screen.AvailHeight-height)/2
    ' 設定 HostName 初始值(也可以輸入 IP Address)
    HostName.Value = "MAIL"
    ' 設定 LogDate 初始值
    LogDate.Value = Date2Str(Date())
    ' 設定顯示存檔的初始名稱
    strFileName = HostName.Value & "_" & LogFile.Value & "_" & EventCode.Value & "_" & LogDate.Value & ".csv"
    FileName.Value = strFileName
End Sub

Sub RefreshFileName
    If SkipDate.Checked Then
        strFileName = HostName.Value & "_" & LogFile.Value & "_" & EventCode.Value & ".csv"
    Else
        strFileName = HostName.Value & "_" & LogFile.Value & "_" & EventCode.Value & "_" & LogDate.Value & ".csv"
    End If
    FileName.Value = strFileName
End Sub

Sub DumpEvent
    if len(LogDate.Value) < 8 then
        MsgBox("請輸入 8 碼日期")
        Exit Sub
    else
        ' 將 LogDate 日期加 1,然後再轉換成 TimeGenerated 的格式,以便在 SQL 中篩選資料
        dEndDate = CDate(DateAdd("d", 1, CDate(MID(LogDate.Value ,1 ,4) & "/" & MID(LogDate.Value, 5, 2) & "/" & MID(LogDate.Value, 7, 2))))
        strEndDateTime = Date2Str(dEndDate) & "000000.000000+480"
    end if
    Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate,(Security)}!\\" & HostName.Value & "\root\cimv2")
    if SkipDate.Checked then
        strSQL = "Select * FROM Win32_NTLogEvent WHERE Logfile = '" & LogFile.Value & "' AND EventCode = '" & EventCode.Value & "'"
    else
        strSQL = "Select * FROM Win32_NTLogEvent WHERE Logfile = '" & LogFile.Value & "' AND EventCode = '" & EventCode.Value & "' AND TimeGenerated >= '" &  LogDate.Value & "000000.000000+480' AND TimeGenerated < '" & strEndDateTime & "'"
    end if
    ' 此行只是用來檢視 SQL Query String 是否正確
    ' msgbox(strSQL)
    Set colLoggedEvents = objWMIService.ExecQuery (strSQL)

    Const ForWriting = 2

    Set objFSO = CreateObject("Scripting.FileSystemObject")
        Set objLogFile = objFSO.CreateTextFile( FileName.Value, ForWriting, True)
        objLogFile.Write "Record Number#"
        objLogFile.Write "Date Time#"
        objLogFile.Write "Message"
        objLogFile.WriteLine
    For Each objEvent in colLoggedEvents
        If Mid(objEvent.Message,3,10) <> "192.168.1." Then
            objLogFile.Write objEvent.RecordNumber & "#"
            objLogFile.Write objEvent.TimeGenerated & "#"
            ' 將 Log 當中多餘的跳行去掉
            objEvent.Message = replace(objEvent.Message,vbCRLF,"")
            ' objEvent.Message = mid(objEvent.Message,1,InStr(objEvent.Message,"。")-1)
            objLogFile.Write objEvent.Message
            objLogFile.WriteLine
        End If
    Next
    objLogFile.Close
    ' 提醒使用者程式已跑完
    Msgbox("Finish !")
End Sub

Sub IgnoreDate
    LogDate.Disabled = not (LogDate.Disabled)
    Call RefreshFileName
End Sub

' 因為 date 資料形態如果是 1~9 月或是 1~9 日,不會補 0 ,造成格式錯亂
' 此外 date 當中還有 "/" ,會造成存檔問題,所以利用此函數將日期轉成
' YYYYMMDD 字串格式
Function Date2Str(dDate)
    arrDate = Split(dDate,"/")
    if Len(arrDate(1)) = 1 then
        if Len(arrDate(2)) = 1 then
            strDate = arrDate(0) & "0" & arrDate(1) & "0" & arrDate(2)
        else
            strDate = arrDate(0) & "0" & arrDate(1) & arrDate(2)
        end if
    else
        if Len(arrDate(2)) = 1 then
            strDate = arrDate(0) & arrDate(1) & "0" & arrDate(2)
        else
            strDate = arrDate(0) & arrDate(1) & arrDate(2)
        end if
    end if
    Date2Str = strDate
End Function
</SCRIPT>

<body>
您要 Dump 哪一台電腦的事件記錄(Host Name or IP)
<input type="text" name="HostName" size="30" onChange="RefreshFileName" onMouseOut="RefreshFileName"><br />
<br />
請選擇事件分類
<select name="LogFile" onChange="RefreshFileName">
  <option value="Application">應用程式</option>
  <option value="Security">安全性</option>
  <option value="System">系統</option>
  <option value="Internet Explorer">Internet Explorer</option>
</select>
<br />
<br />
請輸入「事件 ID」<input type="text" name="EventCode" size="10" value="1011" onChange="RefreshFileName" onMouseOut="RefreshFileName"><br />
<br />
<input type="checkbox" name="SkipDate" onClick="IgnoreDate">不要輸入日期<br />
您要 Dump 哪一天的 Log (格式:YYYYMMDD):<input type="text" name="LogDate" size="8" onChange="RefreshFileName" onMouseOut="RefreshFileName"><br />
<br />

<Button onClick="DumpEvent" accessKey="D"><U>D</U>ump to</Button>
<input type="text" name="FileName" size="30" readonly=True><br />
<br />
<ul>
<li>如果您輸入的電腦無法接受管理(例如:防火牆阻擋),將會發生錯誤訊息</li>
</ul>
</body>
</html>

0 意見: