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 strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Recursive Date Modifed Search & Log 1

Status
Not open for further replies.
Jun 8, 2011
30
CA
Hello,

I am in need of a script that recursively looks through a folder tree, determines if any files in a subfolder have been modified in the last 180 days, and then logs the subfolder if not. This script will be used for archiving data.

Example:

Parent Folder
SubFolder 1
SubFolder 1
SubFolder 2
SubFolder 2
SubFolder 1
SubFolder 2
SubFolder 3
SubFolder 1
SubFolder 1
SubFolder 3
SubFolder 1
SubFolder 2

I want to set the Source folder to the "Parent folder". The script will then check each Subfolder, and its subfolders for any files modified in the last 180 days. If nothing in the subfolder has been modified in 180 days, then I want that subfolder written to text file.

Hopefully thats clear. :)

Thanks for the help!
 
What have you tried so far, and where are you stuck? The assistance Geates gave you here thread329-1651080 should certainly get you well on your way to a working script, or close to it.
 
I thought this request with requester looked familiar.

modify the findRecentFile() I posted previous to

1. Rename the function
2. Pass it the age in days you consider a file to render the directory obsolete (intAge = 180)
3. Determine in a file is obsolete. If so, store the sub folder name

-Geates

"I hope I can chill and see the change - stop the bleed inside and feel again. Cut the chain of lies you've been feeding my veins; I've got nothing to say to you!"
-Infected Mushroom

"I do not offer answers, only considerations."
- Geates's Disclaimer
 
Geates...I was hoping not to have to bother you again :)

Your script works well most of the time but I'd really like to get rid of defining the number of /s its looking for. I'd like it to look recursively all the way down the Subfolders.

Additionally, it will sometimes log false positives which I cant explain the reason.

Thanks!

--------------
Current Script
--------------

const ForAppending = 8
set objFSO = CreateObject("Scripting.FileSystemObject")
set objShell = CreateObject("WScript.Shell")
set objTextFile = objFSO.OpenTextFile ("C:\Log.txt", ForAppending, True)

'************************************************************************
' FUNCTIONS'************************************************************************

function getOldProjects(strSource, intAge)
dim objFolder
set objFolder = objFSO.GetFolder(strSource)

for each objSubFolder in objFolder.SubFolders
strLog = strLog & getOldProjects(objSubFolder.Path, intAge)
next

for each objFile in objFolder.Files
if (strRecent = "") then strRecent = objFile.Path
if (objFile.DateLastModified > objFSO.GetFile(strRecent).DateLastModified) then strFile = objFile.Path
next

if (strFile <> "") then
strModDate = objFSO.GetFile(strFile).DateLastModified
strProjectFolder = objFSO.GetParentFolderName(strFile)
if (datediff("d", strModDate, now) > intAge) then
if (ubound(split(strProjectFolder, "\")) = 7) then
strLog = strLog & vbCRLF & strProjectFolder & " | " & objFolder.DateLastModified & " | " & objFolder.DateLastAccessed
end if
end if
end if
'if strLog <> "" then
' msgbox strLog
'End if
getOldProjects = strLog
end function

'************************************************************************
' MAIN'************************************************************************

intAge = 180 '30 days * 6 months
strSource = "S:\Engineering\"

strLog = getOldProjects(strSource, intAge)

Header = "Folder | Last Date Modified | Last Date Accessed"
objTextFile.WriteLine(Header)
objTextFile.WriteLine(strLog)
objTextFile.Close
 
Notice how strRecent is NEVER anything but the first file in the list. Unless the first file in the subfolder is the most recent, the function will return false positives.

Code:
    for each objFile in objFolder.Files
        if (strRecent = "") then strRecent = objFile.Path
        if (objFile.DateLastModified > objFSO.GetFile(strRecent).DateLastModified) then [b]strFile[/b] = objFile.Path
    next

fixed:
Code:
    for each objFile in objFolder.Files
        if (strRecent = "") then strRecent = objFile.Path
        if (objFile.DateLastModified > objFSO.GetFile(strRecent).DateLastModified) then [b]strRecent[/b] = objFile.Path
    next
    [b]strFile = strRecent[/b]

Your current question better asks what your previous question intended. Thus the script is much easier

Code:
function obsoleteDir(strDir, intAge)
	set objFolder = objFSO.GetFolder(strDir)
	for each objSubFolder in objFolder.SubFolders
		strResults = strResults & obsoleteDir(objSubFolder.Path, intAge)
	next
	
	for each objFile in objFolder.Files
		if (datediff("d", objFile.DateLastModified, now) > intAge) then strResults = strResults & objFolder.Path & vbNewLine
		exit for
	next

	obsoleteDir = strResults
end function

-Geates

"I hope I can chill and see the change - stop the bleed inside and feel again. Cut the chain of lies you've been feeding my veins; I've got nothing to say to you!"
-Infected Mushroom

"I do not offer answers, only considerations."
- Geates's Disclaimer
 
Thank you for the reply Geates. I updated the script but the output is not correct. It is displaying subfolders of the subfolders which I do not need to know. I just care about the subfolders of the parent.

--------------
Current Script
--------------

const ForAppending = 8
set objFSO = CreateObject("Scripting.FileSystemObject")
set objShell = CreateObject("WScript.Shell")
set objTextFile = objFSO.OpenTextFile ("C:\LogNEW.txt", ForAppending, True)

'****************************************************************
' FUNCTIONS'*****************************************************

function obsoleteDir(strDir, intAge)
set objFolder = objFSO.GetFolder(strDir)

for each objSubFolder in objFolder.SubFolders
strResults = strResults & obsoleteDir(objSubFolder.Path, intAge)
next

for each objFile in objFolder.Files
if (datediff("d", objFile.DateLastModified, now) > intAge) then strResults = strResults & objFolder.Path & " | " & objFolder.DateLastModified & " | " & objFolder.DateLastAccessed & vbNewLine
exit for
next

obsoleteDir = strResults
end function


'****************************************************************
' MAIN'**********************************************************

intAge = 730 '30 days * 6 months
strDir = "S:\Engineering\Projects\"

strResults = obsoleteDir(strDir, intAge)

Header = "Folder | Last Date Modified | Last Date Accessed"
objTextFile.WriteLine(Header)
objTextFile.WriteLine(strResults)
objTextFile.Close
 
WeiszMCITP said:
{17 Oct 11 15:00} I'd like it to look recursively all the way down the Subfolders.
WeiszMCITP said:
{17 Oct 11 17:14} It is displaying subfolders of the subfolders which I do not need to know. I just care about the subfolders of the parent.

So which is it? You need to clearly define what you need or you'll never get it.
 
I don't have your environment or your mindset. I can only provide the foundation. You must build the rest of the house. Modify the script to output what you need. As my signature states, "I do not offer answers, only considerations."

-Geates

"I hope I can chill and see the change - stop the bleed inside and feel again. Cut the chain of lies you've been feeding my veins; I've got nothing to say to you!"
-Infected Mushroom

"I do not offer answers, only considerations."
- Geates's Disclaimer
 
I've been trying to make the correct modifications, but havent gotten there yet. Thanks for the help. I'll try to explain better.

ParentFolder
SubFolder1
SubSubFolder1
SubSubFolder2
SubSubFolder3
SubFolder2
SubSubFolder1
SubSubFolder2
SubFolder3
SubSubFolder1
SubSubFolder2

From my tree, I want to set my source to ParentFolder. I then want to walk the tree for each SubFolder. If anything in the SubSubFolders have not been modified in X number of days, I want to log SubFolder. Then I want to go to SubFolder2 and look at all of its SubSubFolders. If nothing has been modified in X days, I want to log SubFolder2.

Hopefully that helps. I'll keep working on it.

Thanks.
 
1. 30 * 6 does not equal 730.
intAge = 730 '30 days * 6 months

2. If your folder structure is consistent, return the parent folder of the subfolder.

3. Your for loop never loops because of the exit for - which should be inside the IF statement. (My bad, but you should have caught this)

Code:
for each objFile in objFolder.Files
   if (datediff("d", objFile.DateLastModified, now) > intAge) then
      strResults = strResults & [b]objFSO.GetParentFolderName(objFolder.Path)[/b] & " | " & objFolder.DateLastModified & " | " & objFolder.DateLastAccessed & vbNewLine
      [b]exit for
   end if[/b]
next


-Geates

"I hope I can chill and see the change - stop the bleed inside and feel again. Cut the chain of lies you've been feeding my veins; I've got nothing to say to you!"
-Infected Mushroom

"I do not offer answers, only considerations."
- Geates's Disclaimer
 
Hi Geates,

I too tried the GetParentFolderName parameter but it is not working either. I am still receiving tons of subsubfolders in my log. I'll continue to investigate.

--------------
Current Script
--------------

const ForAppending = 8
set objFSO = CreateObject("Scripting.FileSystemObject")
set objShell = CreateObject("WScript.Shell")
set objTextFile = objFSO.OpenTextFile ("C:\AutoCADNEW.txt", ForAppending, True)

'****************************************************************
' FUNCTIONS'*****************************************************

function obsoleteDir(strDir, intAge)
set objFolder = objFSO.GetFolder(strDir)

for each objSubFolder in objFolder.SubFolders
strResults = strResults & obsoleteDir(objSubFolder.Path, intAge)
next

for each objFile in objFolder.Files
if (datediff("d", objFile.DateLastModified, now) > intAge) then
strResults = strResults & objFSO.GetParentFolderName(objFolder.Path) & " | " & objFolder.DateLastModified & " | " & objFolder.DateLastAccessed & vbNewLine
exit for
end if
next

obsoleteDir = strResults
end function


'****************************************************************
' MAIN'**********************************************************

intAge = 180 '30 days * 6 months
strDir = "P:\AutoCad\Projects"

strResults = obsoleteDir(strDir, intAge)

Header = "Folder | Last Date Modified | Last Date Accessed"
objTextFile.WriteLine(Header)
objTextFile.WriteLine(strResults)
objTextFile.Close
 
please surround your code in [ignore]
Code:
 ...
[/ignore] tags to maintain formatting.
Process TGML

-Geates

"I hope I can chill and see the change - stop the bleed inside and feel again. Cut the chain of lies you've been feeding my veins; I've got nothing to say to you!"
-Infected Mushroom

"I do not offer answers, only considerations."
- Geates's Disclaimer
 
so you only want to look at the files in the subsub folders. use a "recursion counter" Make sure to dim a variable in the global scope. Add to it at the beginning of the recursive function and subtract from it at the end. Only check files during the 2nd recursion level.

Code:
[red]dim intRecursionLevel[/red]

'****************************************************************
' FUNCTIONS
'*****************************************************

function obsoleteDir(strDir, intAge)
	[red]intRecursionLevel = intRecursionLevel + 1[/red]
	set objFolder = objFSO.GetFolder(strDir)
	for each objSubFolder in objFolder.SubFolders
		strResults = strResults & obsoleteDir(objSubFolder.Path, intAge)
	next
	
	[red]if (intRecursionLevel = 2) then[/red]
		for each objFile in objFolder.Files
			if (datediff("d", objFile.DateLastModified, now) > intAge) then
				strResults = strResults & objFSO.GetParentFolderName(objFolder.Path) & " | " & objFolder.DateLastModified & " | " & objFolder.DateLastAccessed & vbNewLine
				exit for
			end if
		next
	[red]end if
	intRecursionLevel = intRecursionLevel - 1[/red]
	obsoleteDir = strResults
end function

-Geates

"I hope I can chill and see the change - stop the bleed inside and feel again. Cut the chain of lies you've been feeding my veins; I've got nothing to say to you!"
-Infected Mushroom

"I do not offer answers, only considerations."
- Geates's Disclaimer
 
Geates,

Sorry to be such a pain, but it's getting closer.

It is displaying the correct paths now, however it is displaying them multiple times. It appears multiple subsubfolders are causing a log event which logs several of the same folder.

The goal is if any file in any of the subsubfolders has not been modified in 180 days, flag the subfolder once.

Thanks!
 
Because of the objFSO.GetParentFolderName(objFolder.Path). As it only occurs on the 2nd level, it will always return the same thing. Replace that with objFolder.Path

-Geates

"I hope I can chill and see the change - stop the bleed inside and feel again. Cut the chain of lies you've been feeding my veins; I've got nothing to say to you!"
-Infected Mushroom

"I do not offer answers, only considerations."
- Geates's Disclaimer
 
Geates,

The output now looks correct but there is a significant amount of false positives (Folders that have been modified within 180 days).

Thanks!
 
That would suggest the logic isn't exactly right. Bare in mind, a folder's timestamp does not necessarily correspond to the contents timestamps. In wother others, if a file is modified in September, that modification date is NOT reflected on the folders timestamp. The modification did not happen on the folder, it happened in the folder content. The false positive are likely not false.

For verification, include in your output the timestamps of the file that caused the false positive. I think you will quickily notice the "problem".

-Geates

NOTE: You're not bugging me. I enjoy helping others with coding issue. I just ask that a measure of effort is put to understanding the issue.

"I hope I can chill and see the change - stop the bleed inside and feel again. Cut the chain of lies you've been feeding my veins; I've got nothing to say to you!"
-Infected Mushroom

"I do not offer answers, only considerations."
- Geates's Disclaimer
 
Geates,

We've been testing this solution for a couple weeks now and I think it is pretty solid. I'll post the entire code so others can work with it.

Thanks!

------
Code
------
const ForAppending = 8
dim intRecursionLevel

set objFSO = CreateObject("Scripting.FileSystemObject")
set objShell = CreateObject("WScript.Shell")
set objTextFile = objFSO.OpenTextFile ("C:\Log.txt", ForAppending, True)

'****************************************************************
' FUNCTIONS'*****************************************************

function obsoleteDir(strDir, intAge)
intRecursionLevel = intRecursionLevel + 1
set objFolder = objFSO.GetFolder(strDir)

for each objSubFolder in objFolder.SubFolders
strResults = strResults & obsoleteDir(objSubFolder.Path, intAge)
next

if (intRecursionLevel = 3) then
for each objFile in objFolder.Files
if (datediff("d", objFile.DateLastModified, now) > intAge) then
strResults = strResults & objFolder.Path & vbNewLine
exit for
end if
next
end if

intRecursionLevel = intRecursionLevel - 1
obsoleteDir = strResults
end function


'****************************************************************
' MAIN'**********************************************************

intAge = 1095 'Number of Days Old
strDir = "G:\Data"

strResults = obsoleteDir(strDir, intAge)

objTextFile.WriteLine(strResults)
objTextFile.Close
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top