use File::Path; use File::Copy; # Queensbridge Near-side Backup Script # # Written by: Mike Brooman # Last modified: 27/07/05 # Contact: dev@escanti.net # # All backup locations require a fully qualified UNC path # Debug mode - set to "true" to prevent tidy up, copying and archival $debug = false; # Global paths (all require trailing double slash - \\) $backupPath = "D:\\"; $dailyPath = "DailyBackup\\"; $weeklyPath = "WeeklyBackup\\"; $compressedPath = "compressed\\"; # Occurances of each backup to keep $keepDaily = 4; $keepWeekly = 4; # When deleting old archives, check this many days previous have also been deleted $checkDelete = 7; # Day the weekly backup occurs (0 = Sunday, 1 = Monday ... 6 = Saturday) $weeklyOccurs = 6; # Handle student documents year-group exception. # - Allocates year groups to separate directories for faster access to archives $localStudentDir = "DocsStudents"; # Daily and weekly paths to be backed-up. All daily paths are also archived weekly. # Format : "," # - NB: NO SPACES AROUND COMMA! # - Ensure single backslashes are escaped with an additional backslash # - If attempting to map an administrative/hidden share remember to escape the $ with a backslash # - eg. server\\c\$ would be the C drive on a machine called 'server' # # Example: \\Homer\Sharename into the local directory ThisShareName # "Homer\\Sharename,ThisShareName" @daily = ( "queensbridge.pri\\dfs\\Alice,Alice", "queensbridge.pri\\SYSVOL,SYSVOL", "Homer\\DocsStudents\$,DocsStudents", "Homer\\BackupTeaching\$,DocsTeaching", "Homer\\DocsOffice\$,DocsOffice", "Homer\\DocsAdmin\$,DocsAdmin", "Homer\\ProfStudents\$,ProfStudents", "Homer\\ProfTeaching\$,ProfTeaching", "Homer\\ProfOffice\$,ProfOffice", "Homer\\ProfAdmin\$,ProfAdmin", "Bart\\ExchangeBackup,Exchange" ); @weekly = ( "Homer\\General,General", "Homer\\Leadership,Leadership", "Homer\\LSU,LSU", "Homer\\StaffCommon,StaffCommon", "Homer\\StudentPublic,StudentPublic", "Homer\\Admin,Admin", "queensbridge.pri\\dfs\\Drivers,Drivers", "queensbridge.pri\\dfs\\Apps,Apps", "queensbridge.pri\\dfs\\Packages,Packages", "queensbridge.pri\\dfs\\ServerSide,ServerSide", "Marge\\Facility,Facility" ); # *********************** SCRIPT STARTS HERE ************************** # DONT CHANGE ANYTHING BELOW HERE UNLESS YOU KNOW WHAT'S GOING ON :oP # Set prefix for UNCs $UNCprefix = "\\\\"; # Unmap all drives system("net use z: /delete /y"); # Create todays dir ($tsec,$tmin,$thour,$tmday,$tmon,$tyear,$twday,$tyday,$tisdst)=formatTime(time()); $today = $tyear.$tmon.$tmday; if ($twday != $weeklyOccurs) { $sendTo = $dailyPath; } else { $sendTo = $weeklyPath; } $fullPath = $backupPath.$sendTo.$today; mkdir ($fullPath); ### LOGGING $todaysLog = $backupPath.$sendTo.$today."\\".$today.".log"; open (LOG, "> $todaysLog"); print LOG "*** Queensbridge School - iBackup ***\n\n"; close LOG; ### TIDY UP # Sort out dates for removing live copies prior to yesterday / previous week $liveDel = time() - (24 * 60 * 60); $dailyDel = time() - ($keepDaily * 24 * 60 * 60); $weeklyDel = time() - ($keepWeekly * 7 * 24 * 60 * 60); for ($i = 0; $i < $checkDelete; $i++) { ($lsec,$lmin,$lhour,$lmday,$lmon,$lyear,$lwday,$lyday,$lisdst)=formatTime($liveDel - ($i * 24 * 60 * 60)); push (@liveDelete, $lyear.$lmon.$lmday); ($dsec,$dmin,$dhour,$dmday,$dmon,$dyear,$dwday,$dyday,$disdst)=formatTime($dailyDel - ($i * 24 * 60 * 60)); push (@dailyDelete, $dyear.$dmon.$dmday); ($wdsec,$wdmin,$wdhour,$wdmday,$wdmon,$wdyear,$wdwday,$wdyday,$wdisdst)=formatTime($weeklyDel - ($i * 24 * 60 * 60)); push (@weeklyDelete, $wdyear.$wdmon.$wdmday); } logThis ("* Tidying up..."); # Delete yesterday's live folder ready for today's near-side copy foreach $deleteLive (@liveDelete) { $delete = $backupPath.$dailyPath.$deleteLive; if (-e $delete) { logThis ("NUKING: ".$delete); if ($debug ne 'true') { rmtree($delete, 0, 0); } logThis ("Deletion complete."); } else { logThis ("NOT EXIST: ".$delete); } if ($twday == $weeklyOccurs) { $delete = $backupPath.$weeklyPath.$deleteLive; if (-e $delete) { logThis ("NUKING: ".$delete); if ($debug ne 'true') { rmtree($delete, 0, 0); } logThis ("Deletion complete."); } else { logThis ("NOT EXIST: ".$delete); } } } # Delete archives prior to $keepDaily days ago foreach $deleteDaily (@dailyDelete) { $delete = $backupPath.$dailyPath.$compressedPath.$deleteDaily; if (-e $delete) { logThis ("NUKING: ".$delete); if ($debug ne 'true') { rmtree($delete, 0, 0); } logThis ("Deletion complete."); } else { logThis ("NOT EXIST: ".$delete); } } # If day is the $weeklyOccurs day, delete archives prior to $keepWeekly weeks ago if ($twday == $weeklyOccurs) { foreach $deleteWeekly (@weeklyDelete) { $delete = $backupPath.$weeklyPath.$compressedPath.$deleteWeekly; if (-e $delete) { logThis ("NUKING: ".$delete); if ($debug ne 'true') { rmtree($delete, 0, 0); } logThis ("Deletion complete."); } else { logThis ("NOT EXIST: ".$delete); } } } ### COPYING logThis ("* COPYING"); $fullPath = $backupPath.$sendTo.$today; # Create list of backup items @backupItems = @daily; if ($twday == $weeklyOccurs) { push (@backupItems, @weekly); } # Loop backup list and copy files foreach $item (@backupItems) { ($unc, $local) = split(/,/, $item); ($server, $0) = split(/\\/, $unc); $execThis = "regedit /S reg/".$server.".reg"; system($execThis); logThis ("Map backup drive (".$UNCprefix.$unc."):"); $execThis = "net use z: ".$UNCprefix.$unc." >> ".$todaysLog; system ($execThis); logThis ("Copying: ".$local); if ($local eq $localStudentDir) { opendir STUDENTS, "Z:\\"; @StudentDirs = readdir STUDENTS; closedir STUDENTS; foreach $student (@StudentDirs) { if (($student ne ".") && ($student ne "..")) { $thisYear = substr($student,0,2); $fullStudent = "Z:\\".$student; if (-d $fullStudent) { if ($thisYear =~ /\d/) { $execThis = "xxcopy z:\\".$student."\\*.* ".$backupPath.$sendTo.$today."\\".$local."-".$thisYear."\\".$student." /E /YY >> ".$todaysLog; if ($debug ne 'true') { system ($execThis); } else { logThis($execThis); } } else { $execThis = "xxcopy z:\\".$student."\\*.* ".$backupPath.$sendTo.$today."\\".$local."-Misc\\".$student." /E /YY >> ".$todaysLog; if ($debug ne 'true') { system ($execThis); } else { logThis($execThis); } } } } } } else { $execThis = "xxcopy z:\\*.* ".$backupPath.$sendTo.$today."\\".$local." /E /YY >> ".$todaysLog; logThis ("Executing: ".$execThis); if ($debug ne 'true') { system ($execThis); } else { logThis($execThis); } } logThis ("Unmap backup drive:"); $execThis = "net use /delete z: >> ".$todaysLog; system ($execThis); } ### ARCHIVING logThis ("* ARCHIVING"); # Compress today's backup for archival $fullPath = $backupPath.$sendTo.$today; opendir BACKUPTHIS, $fullPath; @BackupDirs = readdir BACKUPTHIS; closedir BACKUPTHIS; $ArchivePath = $backupPath.$sendTo.$compressedPath.$today; logThis ("Creating: ".$ArchivePath); mkdir ($ArchivePath); foreach $dir (@BackupDirs) { $thisDir = $fullPath."\\".$dir; if (-d $thisDir) { if (($dir ne ".") && ($dir ne "..")) { logThis("Archiving: ".$dir); $compress = $ArchivePath."\\".$dir.".rar"; $execThis = "rar a -r ".$compress." ".$thisDir."\\*.* >> ".$todaysLog; if ($debug ne 'true') { system($execThis); } else { print $execThis."\n"; } } } } logThis ("* ARCHIVING COMPLETE"); # Parse mahoosive log file open (LOG, "$todaysLog") or die ("Unable to open file"); @logs = ; close LOG; $newLog = $backupPath.$sendTo.$today."\\".$today." Short.log"; open (NEWLOG, ">$newLog"); foreach $line (@logs) { if ((index($line, "Z:\\") < 0) && (index($line, "Adding ") < 0)) { print NEWLOG $line; } else { if (index($line, "Copy failed") > 0) { print NEWLOG $line; } } } close NEWLOG; $fullPath = $backupPath.$sendTo.$today; $ArchivePath = $backupPath.$sendTo.$compressedPath.$today; $execThis = "rar a -r ".$ArchivePath."\\fullLog.rar ".$fullPath."\\".$today.".log"; system ($execThis); copy ($newLog, $ArchivePath); # Let everyone know we've finished logThis ("*** iBackup complete"); # This formats time() to be used as YYMMDD - only mday, mon, year are changed sub formatTime { my ($thisTime) = @_; ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime($thisTime); if ($mday < 10) { $mday = "0".$mday; } $mon = $mon + 1; if ($mon < 10) { $mon = "0".$mon; } $year = $year - 100; if ($year < 10) { $year = "0".$year; } return ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst); } sub logThis { ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time()); if ($hour < 10) { $hour = "0".$hour; } if ($min < 10) { $min = "0".$min; } if ($sec < 10) { $sec = "0".$sec; } $thisStamp = "[".$hour.":".$min.".".$sec."]"; my ($log) = @_; open (LOG, ">> $todaysLog"); print LOG "\n".$thisStamp." ".$log."\n"; close LOG; print "\n".$thisStamp." ".$log."\n"; }