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

Searching files by modified date. 4

Status
Not open for further replies.

ponoodle

IS-IT--Management
Dec 10, 2010
135
US
I'm trying to fix some scripts that someone else wrote before I worked here. We want to search all files on specified computers for a specified string, but we only want to search files that have been modified within a certain amount of days. There are two scripts involved.

First Script
Code:
on error resume next
Const ForReading = 1
Set objShell = CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
srcTXT = "C:\scripts\accessed.txt"
Set objFileSrc = objFSO.OpenTextFile(srcTXT, ForReading)

daysOld = InputBox("How many days ago was the file modified?")
SearchString = InputBox("What is the string that we are searching for?")


i = 0
Do Until objFileSrc.AtEndOfStream
     Redim Preserve arrFileLines(i)
     arrFileLines(i) = objFileSrc.ReadLine
     i = i + 1
Loop

if i = 0 then
	wscript.quit
end if

objFileSrc.Close


For x = 0 to Ubound(arrFileLines) 
		objShell.Run "cscript ""C:\scripts\findtribal.vbs"" " & arrFileLines(x) & " " & daysOld & " " & SearchString
Next
Second Script
Code:
on error resume next

Dim ArgObj
Set ArgObj = WScript.Arguments

Const FOR_READING = 1
Const ForReading = 1

strFolder = "\\" & ArgObj(0) & "\C$"

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(strFolder)
Set colFiles = objFolder.Files

Set fso2 = CreateObject("Scripting.FileSystemObject")

noofdays = ArgObj(1)

SearchString = ArgObj(2)
wscript.echo "Searching " & ArgObj(0) & " for '" & SearchString & "' within files modified " & noofdays & " days ago."

For Each objFile In colFiles
		filenamepath = objFile.Path
		
		Set ReadFile = fso2.OpenTextFile(filenamepath, ForReading, TristateFalse) 
		thisTXT =	ReadFile.ReadAll 

		ValueSearch = InStr(1,thisTXT,SearchString,1) 
			If ValueSearch>=1 Then 
				wscript.echo  "Found '"+ Searchstring + "' in "+ objFile.Path
				Wscript.Sleep 5000
			end if
Next
ShowSubFolders(objFolder)


Sub ShowSubFolders(objFolder)
on error resume next
Set colFolders = objFolder.SubFolders

For Each objSubFolder In colFolders
	If objSubFolder.Path <> strFolder & "\System Volume Information" then

		Set colFiles = objSubFolder.Files

		
		For Each objFile In colFiles
			'if trim(left(objFile.datelastmodified-nofdays,10)) = trim(left(date-noofdays,10)) then
			IF Date - DateValue(objFile.datelastmodified) < 15 THEN 
			filenamepath = objFile.Path
				Set ReadFile = fso2.OpenTextFile(filenamepath, ForReading, TristateFalse) 
				thisTXT =	ReadFile.ReadAll 
				ValueSearch = InStr(1,thisTXT,SearchString,1) 
				If ValueSearch>=1 Then 
					wscript.echo "Found '"+ Searchstring + "' in "+ objFile.Path
					Wscript.Sleep 5000
				end if
			end if
		Next
		ShowSubFolders(objSubFolder)
	end if
Next
End Sub


WScript.Echo objFile.Path
WScript.Echo objFile.Name
wscript.echo "completed"
Wscript.Sleep 999999999

Thanks for any help.
 
I forgot to mention the problem. The script seems to search all files, not just the ones modified since the number of days we tell it.
 
Just some quick observations:

Your date comparison code shows two lines, one commented out and one not:
Code:
[COLOR=green]'if trim(left(objFile.datelastmodified-nofdays,10)) = trim(left(date-noofdays,10)) then[/color]
IF Date - DateValue(objFile.datelastmodified) < 15 THEN
The commented-out code has a type (nofdays), but the uncommented code should work (the date comparison part, anyway) if you replace the hard-coded 15 with "noofdays"
Code:
IF Date - DateValue(objFile.datelastmodified) < noofdays THEN

Other issues: The first part of the second script looks at all the files in the root of c (with no date check).

Then it lets ShowSubFolders recursively check the files in all subfolders. Why not use one folder that checks the files in the root, then recursively checks all files in all subfolders? Have a look at mrmovie's file/folder recursion example here: faq329-5515

 
Thank you for the quick response.

I actually tried your first suggestion before I posted here. I am pretty much clueless about VB, or any programming language, so I am happy to see that a knowledgeable person had the same idea. Unfortunately, the script still found older test files with the same search string. So, any other ideas?

As far as the recursive search part, like I said, I am clueless about programming. Is this something that has to be fixed, or is that only about efficiency?

Thanks again.
 
Try the code below for the second script:
Code:
Option Explicit
Dim ArgObj
Set ArgObj = WScript.Arguments

Const ForReading = 1

Dim strFolder, objFSO, objFolder, noofdays, SearchString
strFolder = "\\" & ArgObj(0) & "\C$"

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(strFolder)

noofdays = ArgObj(1)
SearchString = ArgObj(2)
wscript.echo "Searching for '" & SearchString & "' within files modified " & noofdays & " days ago."

ShowSubFolders(objFolder)


Sub ShowSubFolders(objFolder)
   Dim objSubFolder, objFile, colFolders, colFiles
   Dim filenamepath, ReadFile, ValueSearch, thisTXT
   Set colFolders = objFolder.SubFolders
   If InStr(objFolder.Path, "System Volume Information") = 0 then

      Set colFiles = objFolder.Files
        
      For Each objFile In colFiles
         If Date - DateValue(objFile.datelastmodified) < noofdays Then
            filenamepath = objFile.Path
            Set ReadFile = objFSO.OpenTextFile(filenamepath, ForReading)
            thisTXT = ReadFile.ReadAll
            ValueSearch = InStr(1,thisTXT,SearchString,1)
            If ValueSearch>=1 Then
               wscript.echo "Found '"+ Searchstring + "' in "+ objFile.Path
               Wscript.Sleep 5000
            End If
         End If
      Next

      For Each objSubFolder In colFolders
         ShowSubFolders(objSubFolder)
      Next
   End If

End Sub
 
Thanks again. I really appreciate your help.

Now it doesn't find any of the files though. Technically you solved my first problem though, since it doesn't find the old files anymore either.

I supply the criteria, a command prompt flashes quickly, then nothing.

 
Not really sure. You can test the second script on its own by putting hard-coded values temporarily, like this:
Code:
Option Explicit
Dim ArgObj
Set ArgObj = WScript.Arguments

Const ForReading = 1

Dim strFolder, objFSO, objFolder, noofdays, SearchString
[COLOR=blue]strFolder = "\\computername\C$"[/color]

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(strFolder)

[COLOR=blue]noofdays = 100
SearchString = "mysearchvalue"[/color]
...
Run the script from a command prompt, typing CSCRIPT filename.vbs. At least the command window will not disappear this way.
 
It runs on it's own, finds the correct files, and then I get a runtime error: permission denied. That might work if I can use the error message as a way to know that the script is finished I guess. The two scripts won't work together though and the first one is unchanged. Does that mean that the second script is having trouble receiving the info from the first?

 
I added wscript.echo "test" just before END SUB, and it did echo test more times than I can see and I still get the permission denied error. So it looks to me like it gets to the end of the script. I figure that might help a little.

Thanks again.
 
Possibly a permissions issue on a file. You have to determine which line of code is giving you the error. Let's say the error happens on this line:
Set ReadFile = objFSO.OpenTextFile(filenamepath, ForReading)

You add error trapping around that line like this:
Code:
[COLOR=blue]On Error Resume Next[/color]
Set ReadFile = objFSO.OpenTextFile(filenamepath, ForReading)
[COLOR=blue]If Err.number <> 0 Then 
   wscript.echo "Got Err#" & Err.Number & ": " & Err.Description & " on filename " & filenamepath
End If
On Error Goto 0[/color]

"On Error Resume Next" will ignore all runtime errors (a bad thing that can lead to unexpected results, unless you trap the errors and take appropriate action)

"On Error Goto 0" will again allow runtime errors to occur.
 
That actually was the line. Now it tells me which file was the problem (a system file), but now I get runtime error: Object required: 'ReadFile' a few lines down. It was the next line before I added the code you just gave me.

Code:
thisTXT = ReadFile.ReadAll
 
What about this ?
Code:
For Each objFile In colFiles
  If Date - DateValue(objFile.datelastmodified) < noofdays Then
    filenamepath = objFile.Path
    On Error Resume Next
    Set ReadFile = objFSO.OpenTextFile(filenamepath, ForReading)
    On Error GoTo 0
    If Err.Number <> 0 Then
      Wscript.echo "Got Err#" & Err.Number & ": " & Err.Description & " on filename " & filenamepath
    Else
      thisTXT = ReadFile.ReadAll
      ValueSearch = InStr(1, thisTXT, Searchstring, 1)
      If ValueSearch >= 1 Then
        Wscript.echo "Found '" + Searchstring + "' in " + objFile.Path
        Wscript.Sleep 5000
      End If
    End If
  End If
Next

Hope This Helps, PH.
FAQ219-2884
FAQ181-2886
 
Thanks PHV, but I still get the same error.

Is programming always this frustrating? I only every did really easy stuff for the few classes I had to take in school.
 
Before getting further into this, are the files you are looking in of a certain type? For example, only TXT files? If you can narrow down the file types, your search would run a heckuva lot faster.

poonoodle said:
Is programming always this frustrating?
There are always growing pains when learning a language. If you learn a language, you have to take the bits and pieces that you learn, and apply them further. For example, I demonstrated how to add error trapping to the "OpenTextFile" line. That worked, but you are getting another error in the "ReadAll" line... So, you should now be able to apply the same error trapping arround the "ReadAll"... HOWEVER, if you narrow the search, this may be unnecessary, hence my first question.
 
It could be any of several types. When people access a certain file on our network, we can't have them save it locally. We're pretty sure that we have it locked down and they wouldn't be able to save it, but we need to be REALLY sure that they didn't. We can tell what PC's access the file and the file has a hidden string in it that we search for. We just don't want to search every file on every PC that accesses the file, hence the modified date idea.

As far as programming in general, I am a network guy and I have always been in awe of what you programmers can do.
 
Try the code below; should eliminate all errors and instead show errors at the "problem files":
Code:
Sub ShowSubFolders(objFolder)
   Dim objSubFolder, objFile, colFolders, colFiles
   Dim filenamepath, ReadFile, ValueSearch, thisTXT
   Set colFolders = objFolder.SubFolders
   If InStr(objFolder.Path, "System Volume Information") = 0 then

      Set colFiles = objFolder.Files

      For Each objFile In colFiles
         If Date - DateValue(objFile.datelastmodified) < noofdays Then
            filenamepath = objFile.Path
            On Error Resume Next
            Set ReadFile = objFSO.OpenTextFile(filenamepath, ForReading)
            If Err.number <> 0 Then
               wscript.echo "Got Err#" & Err.Number & ": " & Err.Description & " on filename " & filenamepath
            Else
               thisTXT = ReadFile.ReadAll
	            If Err.number <> 0 Then
	               wscript.echo "Got Err#" & Err.Number & ": " & Err.Description & " on filename " & filenamepath
	            Else
	               ValueSearch = InStr(1,thisTXT,SearchString,1)
	               If ValueSearch>=1 Then
	                  wscript.echo "Found '"+ Searchstring + "' in "+ objFile.Path
	                  Wscript.Sleep 5000
	               End If
	            End If
            End If
         End If
      Next

      For Each objSubFolder In colFolders
         ShowSubFolders(objSubFolder)
      Next
   End If

End Sub
 
That worked great. I got a list of errors, but it completed and only found the files that is should.

It only works when I run it by itself though, with the variables hard coded. When I use the first script, I still get the same problem. It finds files that are older than I want. This makes me think that the problem is with the first script.
 
Code:
For x = 0 to Ubound(arrFileLines)
        objShell.Run "cscript ""C:\scripts\findtribal.vbs"" " & arrFileLines(x) & " " & daysOld & " " & SearchString
Next
Something looks odd to me with the quotes in the objShell.Run line. If I remember correctly the entire .Run argument must be enclosed in quotes.

I would suggest using the echo command or logging your .run argument to a file and double checking to make sure it is what you expect.
 
I see no need for two scripts... Let's try to combine it into one script. The code below would replace everything in the second script (except for the ShowSubFolders sub), and then you can skip the first script entirely. (put this together quickly, not tested):
Code:
Option Explicit
Dim strFolder, objFSO, objFolder, noofdays, SearchString
Dim srcTXT, objFileSrc, arrFileLines(), i, x

Const ForReading = 1
Set objFSO = CreateObject("Scripting.FileSystemObject")
srcTXT = "C:\scripts\accessed.txt"

Set objFileSrc = objFSO.OpenTextFile(srcTXT, ForReading)

noofdays = InputBox("How many days ago was the file modified?")
SearchString = InputBox("What is the string that we are searching for?")

i = 0
Do Until objFileSrc.AtEndOfStream
     Redim Preserve arrFileLines(i)
     arrFileLines(i) = objFileSrc.ReadLine
     i = i + 1
Loop

If i = 0 then
    wscript.quit
End If
objFileSrc.Close

For x = 0 to Ubound(arrFileLines)
	Wscript.echo "Searching for '" & SearchString & "' within files modified " & noofdays & " days ago."
	ShowSubFolders(objFolder)
Next
 
Line 35, 4 runtime error: Object required: 'objFolder'

It's the line: Set colFolders = objFolder.SubFolders

Code:
Sub ShowSubFolders(objFolder)
   Dim objSubFolder, objFile, colFolders, colFiles
   Dim filenamepath, ReadFile, ValueSearch, thisTXT
   Set colFolders = objFolder.SubFolders
   If InStr(objFolder.Path, "System Volume Information") = 0 then

I have been looking online all day to figure this out, but I got nothing. I hate to keep bugging you guys with the same problem. It does feel like we're close, though.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top