Perl Script to Backup Event Logs (Updated)

codeYears ago, I had hacked up various pieces of code to create a variant to the event logs backup scripts that are floating around the internet. There is a script that I have seen that comes with (at least) the Windows Perl releases. This is an updated script for use with Perl and Windows to backup event logs.

The differences between this and the original are the following.
1. Drive letters are hard coded into the code.
2. Options are available, including code to list valid fixed drives.
3. If the folders do not exist, this script will create the folders first prior to backing up the event logs.

Error handling is weak. If the script does not contain a variable in the command, then a help screen will appear; however, if a variable other than those hard coded into the code. I haven’t figured out the “if” statement to fix that just yet.

I would have preferred the drive letters to be automatic and dynamic based on the sub routine, however, this will do for now.

Perl Script

use Win32::EventLog;
#use Win32::OLE qw(in);
#$Win32::OLE::Warn = 3;
use Time::localtime;

$version = "1.00";
$year = 2011;
$build = "2011-05-12";
$myServer=".";     # your servername here.

my %commands = (c => \&cdrive,
                d => \&ddrive,
				e => \&edrive,
				-l => \&listdrives,
				-h => \&help);

if ($#ARGV != 0) {
  print "\nBackup Event Logs $version Copyright (c) $year it.megocollector.com $build\n";
  print "\nUsage: bel <command>\n";
  print "\n<commands>\n";
  print "  c: Backup Event Logs to c drive\n";
  print "  d: Backup Event Logs to d drive\n";
  print "  e: Backup Event Logs to e drive\n";
  print " -l: List valid drives\n";
  print " -h: Help\n";
  exit;
}

$commands{$ARGV[0]}->();

sub cdrive{$backupDrive="c";}
sub ddrive{$backupDrive="d";}
sub edrive{$backupDrive="e";}
sub listdrives{
# Sources: 
# http://www.dreamincode.net/code/snippet2887.htm
# http://accad.osu.edu/~mlewis/Class/Perl/perl.html
# http://www.webmasterkb.com/Uwe/Forum.aspx/perl/9239/List-hard-drives-on-remote-servers

#Perl Example for using the Scripting.FileSystemObject
use Win32;
use Win32::OLE 'in'; #used to convert a collection to an array.
#Enumeration of drive types.
my @driveTypes = ("Unknown", "Removable", "Fixed", "Network", "CDRom", "Ram Disk");

#Get the Scripting FileSystemObject -- this is the entry point
my $obj = "Scripting.FileSystemObject";
my $fs = Win32::OLE->new($obj); #create a new version of the object.

#Request a collection of all drives...
my $drives = $fs->Drives;

#print a report
print "\nDrive Letter Report:\n";

foreach my $drv ( in($drives)) {
	$typ = $drv->{DriveType};
	my $size = sprintf("%3.2f", $drv->{TotalSize}/(1073741824)); #Calculate in GBs
    next unless $drv->{DriveType} == 2;
	print $drv->{DriveLetter} . ": - " . "$driveTypes[$typ] - $size GB\n";	
}
exit;
;}
sub help{
  print "\nBackup Event Logs $version Copyright (c) $year Canon $build\n";
  print "\nUsage: bel <command>\n";
  print "\n<commands>\n";
  print "  c: Backup Event Logs to c drive\n";
  print "  d: Backup Event Logs to d drive\n";
  print "  e: Backup Event Logs to e drive\n";
  print " -l: List valid drives\n";
  print " -h: Help\n";
  exit;
}

#($sec,$min,$hour,$mday,$mon,$year) = localtime();
$year = localtime->year() + 1900;
$month = localtime->mon()+1;
$day = localtime->mday();
$hour = localtime->hour();
$min = localtime->min();
$sec = localtime->sec();
my($dates) = join("-",$year,$month,$day);
my($time) = join(".",$hour,$min,$sec);
my($date) = join("_",$dates,$time);

#my($date)=join("-", ((split(/\s+/, scalar(localtime)))[0,1,2,4]));
my($dest);

# If event log folder does not exist, one will be created.
if (-d "$backupDrive:\\BackupEventLogs")
     {print "";}
else {mkdir ("$backupDrive:\\BackupEventLogs") || print $!;}

for my $eventLog ("Application", "System", "Setup", "Security", "Directory Service", "DNS Server", "File Replication Service", "Internet Explorer", "Media Center") {
my($filename) = join("-",$date,$eventLog);

$handle=Win32::EventLog->new($eventLog, $myServer)
                or die "Can't open $eventLog on $myServer\n";
				
		if (-d "$backupDrive:\\BackupEventLogs\\$eventLog")
			 {print "";}
		else {mkdir ("$backupDrive:\\BackupEventLogs\\$eventLog") || print $!;}		
				
        $dest="$backupDrive:\\BackupEventLogs\\$eventLog\\$filename.evt";
        $handle->Backup($dest)
                or warn "Could not backup and clear the $eventLog EventLog on $myServer ($^E)\n";
                print "$eventLog Copied\n";
        
        $objWMI = Win32::OLE->GetObject('winmgmts:\\\\' . $myServer . '\\root\\cimv2');
	$colLogs = $objWMI->ExecQuery('Select * from Win32_NTEventlogFile Where ' . 'Logfilename = \'' . $eventLog . '\'');
	
        foreach my $objLog (in $colLogs) {
	     $objLog->ClearEventLog();
	     print "$eventLog Cleared\n";
	 }	
	$handle->Close;
}
exit;

Screenshots
bel-1

Script executed without any options.

bel-2
Script executed with the -l option to list fixed drive letters.

bel-3
Script executed with drive c selected.

bel-4
Directory listing of the files and folders created by the script.