Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Andrzejek on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

More detailed script to delete files and folders older than X days within a specific folder

Status
Not open for further replies.

latincork

Technical User
Aug 20, 2013
3
IE
Hi All,
I state in advance that the following solution is not enough for me:" so I have decided to make a more detailed script that does this job and generates a specific log file in .csv format so that I can filter everything as per my reference.


[WAY THE SCRIPT WORKS]
This script is essentially based on two input parameters:
[ul]
[li]targetFolderPath (I believe it's meaningful)[/li]
[li]threshold (all the files/folders older than this value will be deleted)[/li]
[/ul]

Additionally this script is designed in a such a way that if a folder is older than 'threshold' but contains files and/or sub-folders younger than 'threshold', it will not be deleted!

[MY PROBLEM]
The script works fine (I believe) but during my tests (before putting it in production) I discovered that strangely if I reduce the value of the "threshold" parameter to a value lower than 11 for example, then the result is a .csv log file that does NOT contain all the entries (actually 90% of them are missing!!! [yawn]).


[TROUBLESHOOTING STEPS ALREADY FOLLOWED]
I checked more in depth the script and I noticed that the problem is in the recursive call:"manage(childFolderPath)".


[THE SCRIPT]
Code:
'***************************************************
'
' Script Name:	gct.vbs (VBScript) 
' Title:	Garbage Collection Tool
' Author:  	Latin Cork
' Created On:	August 2013
'
' Purpose: 	Given the specific path of a folder, 
'		this  script  deletes  all the files 
'		and subfolders older than a specific
'		number of days
' Note: 	Execute  the   script   with  delete
'		permissions on files and subfolders
'		This version  shows  each file  and 
'		folder deleted along with other
'               details
'
'***************************************************
 
On Error Resume Next

'*************************************************** Main Input

targetFolderPath = "C:\Users\latincork\Desktop\Scripts\GCT\Bin"	' Folder to which this script will be applied to
threshold = 12														' All the files/folders older than this value will be deleted
 
'*************************************************** Set objects & error catching

Dim fso
Dim objFolder
Dim objFile
Dim objSubFolder

Const readMode 	= 1
Const writeMode = 2
Const appendMode = 8
Const informationFlag = 64
Const errorFlag = 48
Const bytesToKB = 1024

outputResult = "Type,Full Path,Size (KB),Last Modified,Age (Days),Action" & vbCrLf
targetFile = "Log_Result_" & date() & ".csv"
targetFile = replace(targetFile, "/", "-")
title = "Garbage Collection Tool"
timeOut = 30 'Number of seconds after which the initial popup window disappears
initialMessage = "Target Folder: " & targetFolderPath & vbCrLf & vbCrLf & "Deleting files older than " & threshold & " days..."
finalMessage = "Task Completed!"

'*************************************************** Main sub-routine

Sub manage(currentFolderPath)
	Dim childFolderPath
	
	Set fso = CreateObject("Scripting.FileSystemObject")
	Set parentFolderPath = fso.GetFolder(currentFolderPath)
	
	'Delete each file
	For Each objFile In parentFolderPath.files
		ageOfCurrentFile = DateDiff("d", objFile.DateLastModified,Now)
		sizeOfCurrentFile = round(objFile.Size / bytesToKB)		
		If ageOfCurrentFile > threshold Then						
			outputResult = outputResult & "File," & objFile.Path & "," & sizeOfCurrentFile & "," & objFile.DateLastModified & "," & ageOfCurrentFile & ",Deleted" & vbCrLf						
			objFile.Delete True
		Else
			outputResult = outputResult & "File," & objFile.Path & "," & sizeOfCurrentFile & "," & objFile.DateLastModified & "," & ageOfCurrentFile & ",Skipped" & vbCrLf
		End If
	Next
	
	'Delete each sub-folder
	For Each objSubFolder In parentFolderPath.Subfolders
		childFolderLastModDate = objSubFolder.DateLastModified		
		childFolderPath = objSubFolder.Path
		ageOfCurrentFolder = DateDiff("d", childFolderLastModDate,Now)
		If isEmpty(childFolderPath) Then
			If ageOfCurrentFolder > threshold Then
				deleteCurrentFolder childFolderPath, childFolderLastModDate 
			Else
				outputResult = outputResult & "Folder," & childFolderPath & ",0," & childFolderLastModDate & "," & ageOfCurrentFolder & ",Skipped" & vbCrLf
			End If
		Else
			manage(childFolderPath)
			If isEmpty(childFolderPath) Then
				If ageOfCurrentFolder > threshold Then
					deleteCurrentFolder childFolderPath, childFolderLastModDate 
				Else
					outputResult = outputResult & "Folder," & childFolderPath & ",0," & childFolderLastModDate & "," & ageOfCurrentFolder & ",Skipped" & vbCrLf
				End If
			Else
				outputResult = outputResult & "Folder," & childFolderPath & ",0," & childFolderLastModDate & "," & ageOfCurrentFolder & ",Skipped" & vbCrLf
			End If
		End If
	Next	
End Sub

'*************************************************** Delete a specific folder and logs this action 

Sub deleteCurrentFolder(myFolderPath, lastModificationDate)
	Set folderToDelete = CreateObject("Scripting.FileSystemObject")
	ageOfFolder = DateDiff("d", lastModificationDate,Now)
	outputResult = outputResult & "Folder," & myFolderPath & ",0," & lastModificationDate & "," & ageOfFolder & ",Deleted" & vbCrLf
	folderToDelete.DeleteFolder(myFolderPath)
End Sub

'*************************************************** Create log file 

Sub createLogFile(filePath)
	set objFSO	= CreateObject("Scripting.FileSystemObject")
	set myFile = objFSO.OpenTextFile(targetFile, writeMode, True, -2)
	myFile.WriteLine outputResult
	myFile.close
End Sub
 
'*************************************************** Check if current folder is empty

Function isEmpty(myFolder)
	Dim objFSO, objFolder
	Set objFSO = CreateObject("Scripting.FileSystemObject")
	If objFSO.FolderExists(myFolder) Then
		Set objFolder = objFSO.GetFolder(myFolder)    
		If objFolder.Files.Count = 0 And objFolder.SubFolders.Count = 0 Then
			isEmpty = True
		Else
			isEmpty = False
		End If
	End If 
End Function

'*************************************************** Show popup message for a limited amount of time only

Sub showMessage(when)
	Select Case when
		Case "begin"
			Set objShell = CreateObject("Wscript.Shell")
			intReturn = objShell.Popup(initialMessage, timeOut, title, informationFlag)
		Case "end"
			MsgBox finalMessage, informationFlag, title		
	End Select	
End Sub

'*************************************************** Start Script

showMessage("begin")
manage(targetFolderPath)
createLogFile(targetFile)
showMessage("end")

I would be very very grateful if somebody is able to help me or to point me to the right direction.

Thanks in advance.

Kind Regards,
Latin Cork :)
 
In general, it is not a good idea to modify a collection of files (move, add, or delete files) while you are iterating through it. I'd suggest marking the files that you want to delete within the loop (add the file names to a new array or dictionary) then when the loop that checks the file dates completes, delete all the files that you have marked.
 
[king][pirate]Hi 'jges',
thanks a lot for your suggestion.

I will keep that in mind....

BTW: the mistery behind that remains not resolved yet..... I guess bloody ms-windows things!!!

Regards,
Latin Cork
 
latincork said:
I will keep that in mind....

Keep it in mind, but also put it in your script. I'm 95% sure it will solve your problem.
 
Hi jges,
The new version of this script is now available and actually (thanks to your advise) it does a better job now. It uses a resized array and you can even do a pre-check just to known in advance which files/folders will be deleted at the end of it.

Please let me know if you want me to share it with you.

Regards,
Latin Cork
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top