Guerrilla Event Log archiving: why and how.

eventI am quite positive that there are as many solutions (both paid and unpaid) for handling Win32 Syslogs as there are SysAdmins out there. On my *NIX machines syslogs are a simple thing, configure Syslog-ng and move on. My Windows Syslogs are a whole different story.

First off, shame on you Microsoft for not providing built in syslogd integration capabilities. With the volume of BSD code in Windows there is just no acceptable reason for this.

But that doesn’t help me. The long term goal is of course to get a central Syslog server set up that will handle and archive log entries from all of my machines (*NIX and Win32), but that is going to take two things:

  1. Time I don’t have.
  2. Money I don’t have.

I need a solution for archiving my Windows event logs right now, in a central location, until I can get the central Syslog server set up. As I mentioned, most of the solutions for doing this on Windows machines (the ones I feel comfortable entrusting my event logs to anyway) cost somewhere in the neighborhood of an arm, a leg, and most of an ear, so those are not viable options. Now what do you do?

Well if you’re me, you roll your own solution. I’ve got several WS2003 servers that I need to log the event data from, because, well to be quite honest, because this network was built by someone that is more of a *NIX SysAdmin, and didn’t set up the Windows side correctly, so there are quite a few odd bugs in this network that will take quite a while to work out.

Now I could go through and manually export the event logs to a file once a month, but that is way too much work. I decided to script the solution to this problem using VBScript (as it is available on all of the Servers I need event log info from).

I give you logArchive.vbs:

'#==============================================================================
'#==============================================================================
'#  SCRIPT.........:  logArchive.vbs
'#  AUTHOR.........:  Joe Glessner
'#  EMAIL..........:  jglessner@gmail.com
'#  VERSION........:  1.0
'#  DATE...........:  30JUL07
'#  COPYRIGHT......:  2008, Joe-IT.com
'#  LICENSE........:  Freeware
'#  REQUIREMENTS...:
'#
'#  DESCRIPTION....:  This script backs up all of the event logs on the
'#                    designated computer, to the specified file server.
'#                    Optionally this script can also clear the event logs once
'#                    they are archived.
'#
'#  NOTES..........:
'#
'#  CUSTOMIZE......:
'#==============================================================================
'#  REVISED BY.....:
'#  EMAIL..........:
'#  REVISION DATE..:
'#  REVISION NOTES.:
'#
'#==============================================================================
'#==============================================================================
'**Start Encode**

'#==============================================================================
'#  START OF SCRIPT
'#==============================================================================
'Option Explicit
'On Error Resume Next

    '#--------------------------------------------------------------------------
    '#  SCRIPT CONFIGURATION SECTION
    '#--------------------------------------------------------------------------
    '#  OPTIONS:
    '#              strComputer = The name of the computer that generated the
    '#                            event logs (e.g. fs01 - use "." for the local
    '#                            machine.
    '#              objDir2 =      The destination directory on the file server.
    '#              clearEVTLogs   "No" does not clear the event logs. "Yes"
    '#                             will clear the event logs once the current
    '#                             logs are archived.
    '#--------------------------------------------------------------------------
    DIM strComputer, objDir2
    strComputer = "dc1"
    objDir2 = "\\SyslogServer\EventLogs$\" & strComputer
    clearEVTLogs = "Yes"

    '#--------------------------------------------------------------------------
    '#  Declare Remaining Variables
    '#--------------------------------------------------------------------------
    Dim current: current = Now
    Dim strDateStamp: strDateStamp = dateStamp(current)
    DIM objDir1: objDir1 = "\\" & strComputer & "\c$\EVT"

    '#--------------------------------------------------------------------------
    '#  Ensure that the Scratch directory exists on the source computer.
    '#--------------------------------------------------------------------------
    Set filesys=CreateObject("Scripting.FileSystemObject")
    If Not filesys.FolderExists(objDir1) Then
        createDir(objDir1)
    End If

    '#--------------------------------------------------------------------------
    '#  Ensure that the destination directory exists on the file server.
    '#--------------------------------------------------------------------------
    If Not filesys.FolderExists(objDir2) Then
        createDir(objDir2)
    End If

    '#--------------------------------------------------------------------------
    '#  Make create backups of the event logs to the Scratch directory.
    '#--------------------------------------------------------------------------
    strPath = objDir2 & "\"
    Set objWMIService = GetObject("winmgmts:" _
        & "{impersonationLevel=impersonate, (Backup, Security)}!\\" _
            & strComputer & "\root\cimv2")
    Set colLogFiles = objWMIService.ExecQuery _
        ("Select * from Win32_NTEventLogFile")
    For Each objLogfile in colLogFiles
        strCopyFile = strDateStamp & "_" & strComputer & "_" _
        & objLogFile.LogFileName & ".evt&"
        strBackupFile = "c:\EVT\" & strDateStamp & "_" _
            & strComputer & "_" & objLogFile.LogFileName & ".evt"
        strBackupLog = objLogFile.BackupEventLog _
            (strBackupFile)
        'WScript.Echo objLogFile.LogFileName & " backed up to " _
        '    & strBackupFile

        '#----------------------------------------------------------------------
        '#  Copy the event logs to the file server.
        '#----------------------------------------------------------------------
        call copyAFile(objDir1, strPath, strCopyFile)

        '#----------------------------------------------------------------------
        '#  Clear the event logs, or not.
        '#----------------------------------------------------------------------
        If clearEVTLogs = "Yes" then
            objLogFile.ClearEventLog()
        End If
    Next

'#==============================================================================
'#  SUBROUTINES/FUNCTIONS/CLASSES
'#==============================================================================
    '#--------------------------------------------------------------------------
    '#  FUNCTION.........:  dateStamp(ByVal dt)
    '#  PURPOSE..........:  Generate an 8-character date stamp from the current
    '#                      VBScript date.
    '#  ARGUMENTS........:  dt = The date stamp to convert.
    '#  EXAMPLE..........:  Dim current: current = Now
    '#                      WScript.Echo dateStamp(current)
    '#  REQUIREMENTS.....:
    '#  NOTES............:  The above example will produce output of 20080730 if
    '#                      run on 07/30/08.
    '#--------------------------------------------------------------------------
    Function dateStamp(ByVal dt)
        Dim y, m, d
        y = Year(dt)
        m = Month(dt)
        If Len(m) = 1 Then m = "0" & m
        d = Day(dt)
        If Len(d) = 1 Then d = "0" & d
        dateStamp = y & m & d
    End Function

    '#--------------------------------------------------------------------------
    '#  FUNCTION........:  copyAFile()
    '#  ARGUMENTS.......:  strScourceFolder = The folder containing the files to
    '#                                        be copied.
    '#                     strTargetFolder = The Destination Folder
    '#                     strFileName = The name and file extension of the file
    '#                                   to be copied.
    '#  PURPOSE.........:  General purpose file copying function.
    '#  EXAMPLE.........:  Wscript.Echo copyAFile("C:\", "\\Server\Share", _
    '#                     & "fileName.txt")
    '#  NOTES...........:  strSourceFolder folder must exist
    '#                     strTargetFolder folder must exist
    '#                     strFileName file must exist in strSourceFolder folder
    '#--------------------------------------------------------------------------
    Function copyAFile( Byval strSourceFolder, Byval strTargetFolder, _
        Byval strFileName)
        Dim objFSO, booOverWrite, strResult
        Set objFSO = CreateObject("Scripting.FileSystemObject")
        If objFSO.FileExists( strSourceFolder & "\" & strFileName) _
            And UCase( strSourceFolder)  UCase( strTargetFolder) Then
            If objFSO.FolderExists( strTargetFolder) Then
                Else
                strResult = "The destination folder does not exist!"
                'copyAFile = strResult
                Exit Function
            End If
            If objFSO.FileExists( strTargetFolder & "\" & strFileName) Then
                strResult = "The file exists, overwritten"
                booOverWrite = vbTrue
            Else
                strResult = "The file does not exist, created"
                booOverWrite = vbFalse
            End If
            objFSO.CopyFile strSourceFolder & "\" _
                & strFileName, strTargetFolder & "\", booOverWrite
        Else
            strResult = "The source file does not exist, or " _
                & "identical Source and Target folders!"
        End If
        'copyAFile = strResult
    End Function

    '#--------------------------------------------------------------------------
    '#  FUNCTION.......:  createDir(strDir)
    '#  ARGUMENTS......:  strDir = UNC path of the directory to create.
    '#  PURPOSE........:  Creates directories.
    '#  EXAMPLE........:  createDir("c:\WSH_TEST\")
    '#                    createDir("c:\WSH_TEST\" & "Files\")
    '#  NOTES..........:  If creating a subdirectory of a directory that does
    '#                    not exist, the parent directory must be created
    '#                    first, as shown in the example.
    '#--------------------------------------------------------------------------
    Function createDir(strDir)
        set filesys=CreateObject("Scripting.FileSystemObject")
        Set objFSO = CreateObject("Scripting.FileSystemObject")
        If Not filesys.FolderExists(strDir) Then
            Set objFolder = objFSO.CreateFolder(strDir)
        End If
    End Function

'#==============================================================================
'#  END OF FILE
'#==============================================================================

So, What does it do? This script will copy the event logs (well technically it creates a backup it doesn’t actually copy the data per se) from the target system to a directory defined by the user, and optionally clear the logs.

You can then use the built in Windows Event Log viewer to open the resulting file and search the event logs for the time period in the file.

How I use this:

I have several copies of this script set up in Windows’ Task Scheduler to run on the first of every month at exactly midnight, with the option to clear the event logs turned on. This allows me to create a Monthly archive of event logs for each Server that it is run against, and when I get a cryptic event log message like “Windows has previously logged the source of this error”, I can go back and search for the referenced previous entry.

Like I said before, this is a temporary system designed to do one thing: archive all of the Event logs from all of my Windows server to a central location until I can get a proper central Syslog server in place. It works flawlessly for the task it was designed to do.

end

7 Responses to Guerrilla Event Log archiving: why and how.

  1. Manuel says:

    Hi Joe
    This looks like an excellent script but it complains in line 150, char 42. I am copied it straight from this webpage using IE7 and tried various ways to copy but it fails. Line below

    And UCase( strSourceFolder) UCase( strTargetFolder) Then

    Would it be too much to ask for help? Is is possible to maybe have it zipped as a download?

    Sorry to ask but i cant figure out why it fails

    You have an excellent site
    thank you for your time
    Manuel

  2. Manuel says:

    Hi Joe
    This looks like an excellent script but it complains in line 150, char 42. I am copied it straight from this webpage using IE7 and FF and tried various ways to copy but it fails. Line below

    And UCase( strSourceFolder) UCase( strTargetFolder) Then

    Would it be too much to ask for help? Is is possible to maybe have it zipped as a download? or email the script to me?

    Sorry to ask but i cant figure out why it fails

    You have an excellent site
    thank you for your time
    Manuel

  3. Manuel says:

    Hi Joe
    Ok i guess i found the solution & comments:

    1 Script doesnt work in XP – i was testing it here and doesnt work
    2 Script works only in W2k & W2k3
    3 The following chars needed to be added to the script:

    Old
    And UCase( strSourceFolder) UCase( strTargetFolder) Then

    New
    And UCase( strSourceFolder) UCase( strTargetFolder) Then

    I did a search of your script which goes back to 2007 and compared it to this one and the ” are missing. Added these 2 and it works now

    Thanks anyway
    Its all working, the script is great

    Manuel

  4. Manuel says:

    Hi
    The characters didnt come out – this is why it has the problem in the website:

    is the (greater than symbol) and (less then symbol)
    …Folder)greater than symbol less then symbol) UCase( strTarget

    found here the script in its original format:
    http://joe-it.com/vbs_logArchive.html

    Cheers
    Manuel

  5. Rich says:

    I know this is an old post but I am having an issue with the calling of copyall. I get the backed up events in c:\EVT but they do not get copied over to my File Server. I am not getting any errors when running either.

  6. Just Joe says:

    That’s interesting Rich. I have not been able to get it to fail the same way. Help me follow along, what exactly have you done?

  7. Rich says:

    Joe,
    I have copied your script and changed the values for these:

    DIM strComputer, objDir2
    strComputer = “Server1”
    objDir2 = “\\Server2\BACKUP\Eventlogs\” & strComputer
    clearEVTLogs = “No”

    That is about all. I then ran a test from the CLI: c:\cscript logArchive.vbs

    I get the backup logs in c:\EVT\ but nothing in \\Server2\BACKUP\Eventlogs\Server1

    It did create the folder Server1 on the remote file server but nothing else. I can show you my script that I copied if it will help.

Leave a comment