Al_Gee has asked for the wisdom of the Perl Monks concerning the following question:

I have a need to copy Windows event logs to a backup location on a number of servers. I was going to use Win32::EventLog, but I am having some difficulty.

We have standard event logs as well as some non-standard .evt files. It took me awhile to realize that I couldn't just read the .evt files in the c:\windows\system32\config directory and use those names as the SourceName for my call to Win32::EventLog->new(). It seems, though, that I can pass the names as the Event Viewer knows them (e.g., the Application event log is actually AppEvent.evt, but you need to use 'Application' rather than 'AppEvent').

Is there some way that I can capture the names as the Event Viewer knows/understands them (in other words, replace my reading of the config directory with something that gives me the correct names), or am I going to be stuck passing them in from the command line or some such? Thanks-- Al

Replies are listed 'Best First'.
Re: Using Win32::Eventlog
by BrowserUk (Patriarch) on Jan 13, 2009 at 21:11 UTC

    According to the docs:

    The method is overloaded in that if the supplied SOURCENAME argument contains one or more literal '\' characters (an illegal character in a SOURCENAME), it assumes that you are trying to open a backup eventlog and uses SOURCENAME as the backup eventlog to open.

    You are remembering to double your backslashes aren't you?

    c:\\windows\\system32\\config\\file.evt

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      Using the full paths to the actual .evt files as if they were backup files is something that I have considered doing, but haven't tried yet. It may be what I have to do.

      Right now, I am just looping through an array of the names that I know and calling Win32::EventLog->new() on each one. I thought that I could just put all the possibilities in the array, and if one didn't exist on a particular server, I could just do a next when the new() failed.

      Unfortunately, that doesn't seem to work. I am testing things now by printing out the number of records and the first record in each log. I stuck a non-existent name ('ducky') in my array to test, and what it did was repeat the information from the Application log file. I do a close at the end of my loop, and the manual specifically says that after a close the handle is no longer any good. I'm not sure what is going on here.

      I went and modified the test code on the man page and set it in a foreach loop with 'Appplication', 'System', and 'Ducky'. 'Ducky' gives the same info as Application, but 'Ducky' doesn't exist. It acts as if new() defaults to Application if it doesn't recognize the SourceName passed. If you give it a NULL entry for SourceName, then it does fail...

      Unless someone has some other suggestions, I guess I'll try using the full paths to the evt files and see how that goes. If that works, I can at least loop through the .evt files in the config directory.

      Thanks--

      Al

        Unless someone has some other suggestions,

        There are three standard names: Application, Security & System. Which map to the system logs:

        C:\windows\SYSTEM32\CONFIG\AppEvent.Evt C:\windows\SYSTEM32\CONFIG\SecEvent.Evt C:\windows\SYSTEM32\CONFIG\SysEvent.Evt

        And the underlying system APIs default to the Application Log on the current system. Ie. The defaulting is done by the system not the module, and is done when: a) the underlying APIs are passed NULLs for the serverName and sourceName parameters; b) one of the passed values is unrecognised. (Dumb defaults, it should return an error, but there you go.)

        As far as I'm aware. the only other files that you can access through these apis, are backups of those three produced by calling the appropriate system API (exposed by the module using the ->Backup() method). You can only do that once you have successfully opened one of those 3, or (perhaps, it is unclear) an existing backup of one of those three. And the way you open a backup is to pass the fully qualified pathname to the New() constructor.

        There are no other options.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Using Win32::Eventlog
by zentara (Cardinal) on Jan 13, 2009 at 20:10 UTC
Re: Using Win32::Eventlog
by mr_mischief (Monsignor) on Jan 13, 2009 at 19:46 UTC
    I don't know of anything Win32-specific to help you, but from the top of my head there's a workaround. If it's a one-to-one mapping, you could always use a hash from file name to the name desired.