Code-Bytes

Windows Script Host Solution: Parameter Driven VBScript application that Deletes or Archives files

Problem: In large corporations, servers get littered with many files that programs or users create and then don't remove. Eventually someone either has to manually clean these files up or add more drive space to avoid a production outage. A script that can be scheduled to automatically delete or archive unwanted files by name patterns and age of the file would be ideal.

Solution Requirements:

  • Create a VBScript that can be started by the Windows Scheduler during "off hours" that and looks for files names using Regular Expressions.
  • Use Microsoft Windows Script Host and VBScript to provide robust callable functions with source code to System Admins
  • Number of days old will also be used to help qualify files to be deleted or archived.
  • Files that are found can be optionally moved to a compressed folder first for a given period of time prior to deletion.
  • Create log files of actions that were taken for auditability and accountability purposes. Log files will be automatically deleted after a period of time you choose.
  • The Scripts are Highly configurable and utilizes command line parameters for maximum flexibility.

Solution Design

  • The Windows Scheduler will run a .Bat file set to a schedule you choose.
  • The .Bat file will contain commands that cause the Windows Script Host to execute VBScripts that delete or archive files and log actions that were taken.
  • Reusable VBScript subroutines named deleteFiles and archiveFiles will be designed to accept directory name and other various parameters so that files can be identified and acted upon.
  • Logs of files that are deleted or archived will be stored in directory named ScriptAuditLogs

Sample Code for two Main Subroutines


deleteFiles(directory,regexp_filename, fileext, greaterthen_i_daysold, sLogName)
archiveFiles(directory,regexp_filename, fileext, greaterthen_i_daysold, sLogName)
'This Lib Contains common code to delete that will delete or archive files. 'Tested with Windows Script Host ver 5.7 on Windows XP Option Explicit '******************************************** '*A wrapper around deleteArchiveFiles '*that causes the sub to delete the files '******************************************** Sub deleteFiles(sDirectoryPath,searchString, ext, iDaysold, sLogName) 'pass "N" to the sub call deleteArchiveFiles (sDirectoryPath,searchString, ext, iDaysold, "N", sLogName) end sub '******************************************** '*A wrapper around deleteArchiveFiles '*that causes the sub to archive the files '******************************************** Sub archiveFiles(sDirectoryPath,searchString, ext, iDaysold, sLogName) 'pass "Y" to the sub call deleteArchiveFiles(sDirectoryPath,searchString, ext, iDaysold, "Y", sLogName) end sub '******************************************** '*Main Subroutine that gets called '*by either archiveFiles or deleteFiles '********* usage examples ******** ' usage--> deleteArchiveFiles "C:\Scripts\","","",-1,"Y","NameOfLogFiletoCreate" --> Example of how to delete all files without taking into account how old they are ' usage--> deleteArchiveFiles "C:\Scripts\","pur","vbs",3,"N","LogFileNameGoesHere" --> Example = delete *pur*.*vbs* that are 3 days old accordint to the system clock ' Note: Log File names will be written to the C:ServerCleanupScripts\deleteLogs\ directory ' and the name should not contain an ext! example "MyTestLog" would write a file @ Const DIR_LOGFILE\MyTestLog.log '******************************************* Sub deleteArchiveFiles(sDirectoryPath,searchString, ext, iDaysold, archiveMode, sLogName) '****************************** '* Note if searchString or ext ="", the values will be treated all names as a match '* it is the equivalent of ALL files with all extentions '***********Create LogFile Objects************* Dim objFS, objLogFile Set objFS = CreateObject("Scripting.FileSystemObject") Dim logString :if archiveMode="Y" then logString="Archived" else logString="Deleted" 'NOTE:DIR_LOGFILE is definded in \lib\const.vbs Set objLogFile = objFS.OpenTextFile(DIR_LOGFILE & sLogName & "_"&Year(Date)&Month(Date)&Day(Date)&"_"&Hour(Now) &Minute(Now) &"-"&Second(Now) & ".log" , 8, true) ObjLogFile.WriteLine "=====" & logString & " the following files @ Start Time: " & Now & "====" '***********End Of Create LogFile Objects************* Dim oFSO Dim oFolder Dim oFileCollection Dim oFile Dim oDupFileFound Dim sTempFileName,sTempExt,sTempDate,sFileSize Dim FileNameRegExpressionObject,FileExtNameRegExpressionObject Set oFSO = CreateObject("Scripting.FileSystemObject") set oFolder = oFSO.GetFolder(sDirectoryPath) set oFileCollection = oFolder.Files 'Iterate through all files to file files to delete. For each oFile in oFileCollection 'If error occurs while accessingfile continue to the next File on error resume next sTempFileName = oFile.Name sTempExt = getFileExtention( oFile.Name) sTempDate = oFile.DateLastModified sFileSize = oFile.Size '************************************************ 'Create Reg Expression objects Set FileNameRegExpressionObject = New RegExp Set FileExtNameRegExpressionObject = New RegExp FileNameRegExpressionObject.IgnoreCase = True FileExtNameRegExpressionObject.IgnoreCase = True FileNameRegExpressionObject.Pattern = searchString FileExtNameRegExpressionObject.Pattern = ext '************************************************** 'Wscript.Echo "File Name = " & oFile.Name & "|file.DateCreated =" & oFile.DateCreated & "|Date Calculation Date()- iDaysOld=" & (Date() - iDaysOld) 'Wscript.Echo "FileExt = " & getFileExtention( oFile.Name) If DateDiff("d", oFile.DateLastModified, Now) >= iDaysOld then 'if ext="" then ext="[:a]*" 'passing "" should result in all file extentions matching [:a]* is a regular expresion that means that. '***If the ext matchs what we are looking for then lets check to see if we have a name match as well if FileExtNameRegExpressionObject.Test(getFileExtention(oFile.Name)) then '****If the ext matchs what we are looking for then lets check to see if we have a name match as well if FileNameRegExpressionObject.Test(getFileName(oFile.Name)) then 'Wscript.Echo "DELETE based on NAME and EXT__> " & oFile.Name '*********************************************************** '* determine if the user wanted to Archive the file Prior '* to deleteing if archiveMode="Y" then If oFSO.FileExists(FILE_ARCHIVE_DIR & oFile.Name) Then '** IF Archive already has a file by that name remove the '** File from the archive and then copy over the new one set oDupFileFound = oFSO.getFile(FILE_ARCHIVE_DIR & oFile.Name) oDupFileFound.Delete(True) oFSO.MoveFile sDirectoryPath & "/" & oFile.Name , FILE_ARCHIVE_DIR else oFSO.MoveFile sDirectoryPath &"/" & oFile.Name , FILE_ARCHIVE_DIR set ts = Nothing end if else 'If we are attempting to clean up the Arcive Directoy so lets campair the last accessed date in steam of the last modified date if( oFile.ParentFolder=FILE_ARCHIVE_DIR) then If DateDiff("d", objFile.DateLastAccessed, Now) >= iDaysOld then oFile.Delete(True) end if else oFile.Delete(True) end if end if '*********************************************************** If Err.Number<>0 Then objLogFile.WriteLine "***************************************************************************" objLogFile.WriteLine ">>ERROR CODE FOUND: "& Cstr(Err.Number) & " " & Err.Description & Now & "<<" objLogFile.WriteLine ">>Proccessing file [" & sTempFileName & "] with Modified Date of " & sTempDate objLogFile.WriteLine "***************************************************************************" Err.Clear else objLogFile.WriteLine sTempFileName & "|" & sFileSize & "|" & sTempDate & "" end if end if end if end if Next '***Cleanup Reexp Obj set FileNameRegExpressionObject = nothing set FileExtNameRegExpressionObject = nothing '***Finish writting to logfile and close the file ***** objLogFile.WriteLine "=====Finish Time: " & Now & "====" objLogFile.Close set objFS = Nothing '***Clean up Set oFSO = Nothing Set oFolder = Nothing Set oFileCollection = Nothing Set oFile = Nothing set oDupFileFound = Nothing end Sub