VB script: archive files based on last date modified

Hello experts,

I hava a ROOT folder that contains multiple subfolders

ROOT\sub1
ROOT\sub2
.....
Every subfolder contains a common folder with the following name 'data' and multiple csv files inside.

I would like to setup an script that perform the following actions:
Loop into every 'data' folder located in every subfolder at ROOT folder
Retain only files modified in the last 24 hours and move the rest of files into an archive  folder named 'archive'  located in the same path of ROOT\sub1, ROOT\sub, etc...
If one of the 'archive' folder doesn't exist in one of the subfolder the script should create  the archive folder
Extra bonus requirement (if possible): based on the datelastmodified of old files, the script should create a date folder 'dd-mm-yyy' into every archive folder and move the files into respectively

Log requirements:
Log files should be named as followed: 'log-archive-files' and should be generated at the same path in which the script is launched
if ROOT folder doesn't exist log output should be: Now & ROOT doesn't exist
If one of the sub folders does't contain data folder log output should be: NOW sub folder path doesn't contains files unable to move files
file.count =0 of one of the data folder is empty log output should be: NOW sub folder path is empty
If no error log output should  be: NOW files have been successfully moved

Thank you in advance for your help.
LVL 1
LD16Asked:
Who is Participating?
 
Bill PrewCommented:
Okay, this should do it all.  Adjust path as needed.  After you run for testing, turn the DEBUG switch off.  Questions welcome.

' Option to display some information to the console (STDOUT) during processing for testing
blnDebug = True

' Text file I/O constants
Const ForReading = 1
Const ForWriting = 2
Const ForAppending = 8

'Create the file system object for creating folders:
Set objFSO = CreateObject("Scripting.FileSystemObject")

' Define folders and files to work with
strScriptDir = objFSO.GetAbsolutePathName(".")
strBaseDir = "B:\EE\EE28631154\Base"
strLogFile = strScriptDir & "\Log-Archive-Files.txt" 
strDataDir = "data"
strArchiveDir = "archive"
intAgeHours = 24

' Make sure input folder exist
If Not objFSO.FolderExists(strBaseDir) Then
   Wscript.Echo Now & " ERROR: Input folder """ & strBaseDir & """ does not exist."
   Wscript.Quit
End If

' Open log file for appending
Set objLog = objFSO.OpenTextFile(strLogFile, ForAppending, True)

' Process first level folders in source folder
intWarnings = 0
For Each objFolder In objFSO.GetFolder(strBaseDir).SubFolders
   If blnDebug Then Wscript.Echo Now & " DEBUG: Processing folder """ & objFolder.Path & """."
   strDataFolder = objFolder.Path & "\" & strDataDir

   ' Process our data folder in this subfolder
   If objFSO.FolderExists(strDataFolder) Then

      ' Process all files in this data folder
      intFiles = 0
      For Each objFile In objFSO.GetFolder(strDataFolder).Files
         If blnDebug Then Wscript.Echo Now & " DEBUG: Processing file """ & objFile.Path & """."
         intFiles = intFiles + 1

         ' Make sure it matches the files we want to copy
         If blnDebug Then Wscript.Echo Now & " DEBUG: File age """ & DateDiff("h", objFile.DateLastModified, Now) & """ hours."
         If DateDiff("h", objFile.DateLastModified, Now) > intAgeHours Then
            
            ' Create dest folder if needed
            strDestFolder = objFolder.Path & "\" & strArchiveDir
            If Not objFSO.FolderExists(strDestFolder) Then
               If blnDebug Then Wscript.Echo Now & " DEBUG: Creating folder """ & strDestFolder & """."
               objFSO.CreateFolder strDestFolder
            End If

            ' Create dated subfolder in archive folder
            strDestFolder = strDestFolder & "\" & GetDate(objFile)
            ' Create dest folder if needed
            If Not objFSO.FolderExists(strDestFolder) Then
               If blnDebug Then Wscript.Echo Now & " DEBUG: Creating folder """ & strDestFolder & """."
               objFSO.CreateFolder strDestFolder
            End If

            ' Move file
            If blnDebug Then Wscript.Echo Now & " DEBUG: Move file """ & objFile.Path & """ to """ & strDestFolder & "\" & objFile.Name & """."
            objFSO.MoveFile objFile.Path, strDestFolder & "\" & objFile.Name
         End If
      Next

      ' Warn if no matching files in this data folder
      If intFiles = 0 Then
         objLog.WriteLine Now & " WARNING: Data folder """ & strDataFolder & """ does not contain any matching files."
         intWarnings = intWarnings + 1
      End If
   Else
      ' Warn if our data folder doesn't exist in this subfolder
      objLog.WriteLine Now & " WARNING: Data folder """ & strDataFolder & """ does not exist."
      intWarnings = intWarnings + 1
   End If
Next

' Log overall job status
If intWarnings = 0 Then
   objLog.WriteLine Now & " SUCCESS: Folders and files have been properly transferred."
Else
   objLog.WriteLine Now & " WARNING: Warnings found during copy, check log entries."
End If

' Wrap up
objLog.Close

Function GetDate (objFile)
   datModified = objFile.DateLastModified
   GetDate = Year(datModified) & "-" & Right("0" & Month(datModified), 2) & "-" & Right("0" & Day(datModified), 2)
End Function

Open in new window

~bp
0
 
Bill PrewCommented:
Will DATA subfolder be immediately below the SUB1 folder level, or could it be deeper in the tree, like HOME\SUB1\DIR2\DIR3\DATA ?

How should the ZIP files with the ARCHIVE folder be named?

What tool can be used to do the ZIPPING, 7ZIP perhaps?

~bp
0
 
NVITCommented:
Retain only files modified in the last 24 hours...
Do you mean this literally? Does the last day qualify? i.e. Today is 3/6/15 4:37 PM. Specifically the last 24 hours is from now to 3/5/15 4:37 PM, but not 3/5/15 3:37 PM

Would the whole day of 3/5/15 qualify?
0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
NVITCommented:
This qualifies files by day.
Note:
- Adjust DirRoot, FNPatt, DaysOldand FNLog to your needs.

@echo off
setlocal
cls
REM 
REM Move ROOT\sub*\data\* files older than 1 day to ROOT\sub*\archive

set DirRoot=c:\RootFolder
set FNPatt=*.csv
set DaysOld=1
set FNLog=%~dp0%log-archive-files.txt

if not exist %DirRoot% echo %date% %time% %DirRoot% does not exist >>%FNLog%
for /d %%a in ("%DirRoot%\sub*") do (
   if not exist "%%a\data" (
      echo %date% %time% "%%a\data" does not exist. Unable to move files >>%FNLog%
   ) else (
      call :DirIsEmpty "%%a\data\*.*"
      if %errorlevel% neq 1 (
         for /d %%A in ("%%a\data") do (
            if not exist "%%A\*.*" (
               echo %date% %time% No files in %%~fA>>%FNLog%"
            ) else (
               md "%%a\archive" 2>nul
               forfiles /d -%DaysOld% /p "%%a\data" /m %FNPatt% /c "cmd /c move @file %%a\archive && echo %date% %time% Moved @path >>%FNLog%"
            )
         )
      )
   )
)
goto :eof

:DirIsEmpty
( dir /b /a "%1" | findstr . ) > nul && (
  REM echo %1 non-empty
  exit /b 1
) || (
  REM echo %1 empty
  echo %date% %time% %1 is empty. >>%FNLog%
  exit /b 0
)

Open in new window

0
 
LD16Author Commented:
@Bill 'data folder' will be immediately bellow subfolder 1 and subfolder 2, etc...
the structure is always the same 'data folder at  level 3:
ROOT\Sub1\data
ROOT\Sub2\data
....
Concerning the 'archive folder' the script is not required to zip the files just to move old files located at the various data folder into 'archive folder' that will be at level3.
ROOT\Sub1\archive
ROOT\Sub2\archive
....

@NewVillageIT: the last day qualify, I was thinking something like this
  If DateDiff("d", file.DateLastModified, Now) < 1

Thank you both for your help.
0
 
LD16Author Commented:
Hello Bill,

Thank you for this script it works perfectly!

I have one question if I want (is not the case but I am curious of this) to add another
strDataDir = "data2" (this folder is exactly in the same level at "data"). I need to re-create all the loops or I can add and Array variable so data folder and data2 folder will be take into account. Archive will collect files from data and data2.
0
 
Bill PrewCommented:
Yes, that could be done, in this case I think it would be as simple as this.  And of course this would still work even if there was only one folder in the array.  Let me know if this makes sense.

' Option to display some information to the console (STDOUT) during processing for testing
blnDebug = True

' Text file I/O constants
Const ForReading = 1
Const ForWriting = 2
Const ForAppending = 8

'Create the file system object for creating folders:
Set objFSO = CreateObject("Scripting.FileSystemObject")

' Define folders and files to work with
strScriptDir = objFSO.GetAbsolutePathName(".")
strBaseDir = "B:\EE\EE28631154\Base"
strLogFile = strScriptDir & "\Log-Archive-Files.txt" 
arrDataDirs = Array("data", "data2")
strArchiveDir = "archive"
intAgeHours = 24

' Make sure input folder exist
If Not objFSO.FolderExists(strBaseDir) Then
   Wscript.Echo Now & " ERROR: Input folder """ & strBaseDir & """ does not exist."
   Wscript.Quit
End If

' Open log file for appending
Set objLog = objFSO.OpenTextFile(strLogFile, ForAppending, True)

' Process first level folders in source folder
intWarnings = 0
For Each objFolder In objFSO.GetFolder(strBaseDir).SubFolders
   ' Process each desired data folder
   For Each strDataDir In arrDataDirs

      If blnDebug Then Wscript.Echo Now & " DEBUG: Processing folder """ & objFolder.Path & """."
      strDataFolder = objFolder.Path & "\" & strDataDir

      ' Process our data folder in this subfolder
      If objFSO.FolderExists(strDataFolder) Then

         ' Process all files in this data folder
         intFiles = 0
         For Each objFile In objFSO.GetFolder(strDataFolder).Files
            If blnDebug Then Wscript.Echo Now & " DEBUG: Processing file """ & objFile.Path & """."
            intFiles = intFiles + 1

            ' Make sure it matches the files we want to copy
            If blnDebug Then Wscript.Echo Now & " DEBUG: File age """ & DateDiff("h", objFile.DateLastModified, Now) & """ hours."
            If DateDiff("h", objFile.DateLastModified, Now) > intAgeHours Then
               
               ' Create dest folder if needed
               strDestFolder = objFolder.Path & "\" & strArchiveDir
               If Not objFSO.FolderExists(strDestFolder) Then
                  If blnDebug Then Wscript.Echo Now & " DEBUG: Creating folder """ & strDestFolder & """."
                  objFSO.CreateFolder strDestFolder
               End If

               ' Create dated subfolder in archive folder
               strDestFolder = strDestFolder & "\" & GetDate(objFile)
               ' Create dest folder if needed
               If Not objFSO.FolderExists(strDestFolder) Then
                  If blnDebug Then Wscript.Echo Now & " DEBUG: Creating folder """ & strDestFolder & """."
                  objFSO.CreateFolder strDestFolder
               End If

               ' Move file
               If blnDebug Then Wscript.Echo Now & " DEBUG: Move file """ & objFile.Path & """ to """ & strDestFolder & "\" & objFile.Name & """."
               objFSO.MoveFile objFile.Path, strDestFolder & "\" & objFile.Name
            End If
         Next

         ' Warn if no matching files in this data folder
         If intFiles = 0 Then
            objLog.WriteLine Now & " WARNING: Data folder """ & strDataFolder & """ does not contain any matching files."
            intWarnings = intWarnings + 1
         End If
      Else
         ' Warn if our data folder doesn't exist in this subfolder
         objLog.WriteLine Now & " WARNING: Data folder """ & strDataFolder & """ does not exist."
         intWarnings = intWarnings + 1
      End If

   Next
Next

' Log overall job status
If intWarnings = 0 Then
   objLog.WriteLine Now & " SUCCESS: Folders and files have been properly transferred."
Else
   objLog.WriteLine Now & " WARNING: Warnings found during copy, check log entries."
End If

' Wrap up
objLog.Close

Function GetDate (objFile)
   datModified = objFile.DateLastModified
   GetDate = Year(datModified) & "-" & Right("0" & Month(datModified), 2) & "-" & Right("0" & Day(datModified), 2)
End Function

Open in new window

~bp
0
 
LD16Author Commented:
Excellent
0
 
LD16Author Commented:
Great, thank you again!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.