VBscript to check for the existance of a file (with the ability to use a wildcard) within a certain time frame
Solution 1
If you use WMI, it supports wildcards.
Dim strPath
strFile = "*.*"
If WScript.Arguments.Count > 1 Then
strPath = WScript.Arguments.Item(0)
strFile = WScript.Arguments.Item(1)
Elseif WScript.Arguments.Count = 1 Then
strPath = WScript.Arguments.Item(0)
Else
End If
Set objFso = CreateObject("Scripting.FileSystemObject")
If Not objFso.FolderExists(strPath) Then
WScript.Echo "Folder path does not exist."
WScript.Quit
Else
'Remove any trailing slash
If Right(strPath, 1) = "\" Then
strPath = Left(strPath, Len(strPath) - 1)
End If
End If
Set objFso = Nothing
If Not IsNull(strPath) And strPath <> "" Then
strQuery = strPath & "\" & strFile
Else
strQuery = strFile
End If
strQuery = Replace(strQuery, "*", "%")
strQuery = Replace(strQuery, "?", "_")
strQuery = Replace(strQuery, "\", "\\")
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}\\" & strComputer & "\root\cimv2")
Set colFiles = objWMIService.ExecQuery _
("Select * From CIM_DataFile Where FileName Like '" & strQuery & "'")
For Each objFile in colFiles
WScript.Echo "Access mask: " & objFile.AccessMask
WScript.Echo "Archive: " & objFile.Archive
WScript.Echo "Compressed: " & objFile.Compressed
WScript.Echo "Compression method: " & objFile.CompressionMethod
WScript.Echo "Creation date: " & objFile.CreationDate
WScript.Echo "Computer system name: " & objFile.CSName
WScript.Echo "Drive: " & objFile.Drive
WScript.Echo "8.3 file name: " & objFile.EightDotThreeFileName
WScript.Echo "Encrypted: " & objFile.Encrypted
WScript.Echo "Encryption method: " & objFile.EncryptionMethod
WScript.Echo "Extension: " & objFile.Extension
WScript.Echo "File name: " & objFile.FileName
WScript.Echo "File size: " & objFile.FileSize
WScript.Echo "File type: " & objFile.FileType
WScript.Echo "File system name: " & objFile.FSName
WScript.Echo "Hidden: " & objFile.Hidden
WScript.Echo "Last accessed: " & objFile.LastAccessed
WScript.Echo "Last modified: " & objFile.LastModified
WScript.Echo "Manufacturer: " & objFile.Manufacturer
WScript.Echo "Name: " & objFile.Name
WScript.Echo "Path: " & objFile.Path
WScript.Echo "Readable: " & objFile.Readable
WScript.Echo "System: " & objFile.System
WScript.Echo "Version: " & objFile.Version
WScript.Echo "Writeable: " & objFile.Writeable
Next
EDIT..........
You can use a WMI event script with the __InstanceCreationEvent
to monitor for new file creation in a specific folder. It looks like this:
strSource = "C:\\somefilepath\\withdoubleshlashes"
strComputer = "."
Set objWMIService = GetObject("winmgmts:" & strComputer & "rootcimv2")
Set colEvents = objWMIService.ExecNotificationQuery _
("SELECT * FROM __InstanceCreationEvent WITHIN 10 WHERE " _
& "Targetinstance ISA 'CIM_DirectoryContainsFile' AND " _
& "TargetInstance.GroupComponent= " _
& "'Win32_Directory.Name=""" & strSource & """'")
Do While True
Set objEvent = colEvents.NextEvent()
copyFile(objEvent.TargetInstance.PartComponent)
Loop
For a full explanation, you can read Monitoring and Archiving Newly Created Files on my blog.
Solution 2
This answer uses Regular Expressions. To make it work it rewrites your pattern format into regular expression format. e.g. *.txt
will become ^.*[.]txt$
.
The following lists text files in C:\Temp
last modified between 5:55 AM and 6:05 AM:
strPath = "C:\Temp"
strFile = "*.txt"
startTime = 555
endTime = 605
Set fso = CreateObject("Scripting.FileSystemObject")
Set folder = fso.GetFolder(strPath)
Set files = folder.Files
Set re = New RegExp
re.IgnoreCase = true
re.Pattern = "^" + Replace(Replace(strFile, ".", "[.]"), "*", ".*") + "$"
For Each f in Files
Set matches = re.Execute(f.Name)
If matches.Count > 0 Then
HM = Hour(f.DateLastAccessed) * 100 + Minute(f.DateLastAccessed)
If HM >= startTime And HM <= endTime Then
WScript.Echo f.Name, f.DateLastAccessed
End If
End If
Next
References:
Th3Cap3
Updated on June 14, 2022Comments
-
Th3Cap3 almost 2 years
Good morning all, I have been trying to pull together a VBscript that takes a file path and a file name (that may have a wildcard in it) from the user when the script is exicuted. The script will then check the specified directory for a file that matches the provided file name and then looks at the last modified date to see if it was created/modified within a certain time frame (i.e. 6am plus or minus 5 minutes). It would then copy said file into a zip file.
So far I have been able to get the arguments working, and I have it setup to grab the current time, look at the files in the folder and match a hard coded filename to one in the folder. This is what I have thus far.
currentTime = Now() filePath = Wscript.Arguments.Item(0) fileName = Wscript.Arguments.Item(1) Set fileSystem = CreateObject("Scripting.FileSystemObject") Set directory = fileSystem.GetFolder(filePath) For each file in directory.Files If file.Name = fileName Then Wscript.echo file.Name & " " & file.DateLastModified end if Next
I am a VBscript noob and I am looking forward to learning the way!
Cap3
-
AutomatedChaos over 11 yearsWhen you are working with WMI services, it enables you to connect it to an event sink. Now you can handle the event really event-based.
-
Nilpo over 11 yearsUsing an event sink here would be the preferred method (as it uses much less overhead), however, the OP does not provide enough information to leverage an event sink. Though it sounds as if using an __InstanceCreationEvent to monitor a specific folder during specific minutes of the day might accomplish the intended task.
-
Th3Cap3 over 11 yearsThis _InstanceCreationEvent will watch for the creation of a file in a specific location? If that is what it does, that could be extremely helpful. I wish I could have been more precise in my post, however I wasn't given much detail on the request either, I am still waiting for more information on how the files are named, when it comes in, if it's deleted, etc... Could you expand on the InstanceCreationEvent?
-
Nilpo over 11 yearsYes, the __InstanceCreationEvent can be used to monitor for the creation of a file in a specific location. You just need to know the file path. See my edit above.
-
Th3Cap3 over 11 yearsThat is very helpful :-), I am going to play with this and see if I can grasp how it flows into the other stuff I wish to do with the script, thank you for your help!
-
Nilpo over 11 yearsNo problem at all. Glad I could help out.
-
Dss about 10 yearsSomething noticed with the __InstanceCreationEvent method is that you can really only reliably monitor a single folder. Adding more folders by either running multiple copies of a script or adding more OR values to the where clause both end with a "quote violation". My memory value for WMI quota is set for 512MB which is the recommended value by microsoft, but I am going to try 1GB to see if that works better. Still I think maybe an FSO solution is best overall if possible, regardless of how nice the instance creation event feature is on paper.
-
Nilpo about 10 years@Dss The __InstanceCreationEvent is system-wide. There's no need to create more than one instance of the event loop. Instead, leave off the directory portion and then check each result you get back for the proper directory or directories.
-
Dss about 10 years@Nilpo You misunderstand... Im talking about monitoring multiple folder paths. If I want to monitor C:\ I can do objWMIService.ExecNotificationQuery("SELECT * FROM __InstanceCreationEvent WITHIN 10 WHERE TargetInstance ISA 'CIM_DirectoryContainsFile' and TargetInstance.GroupComponent='Win32_Directory.Name=""C:\\\\""'") and that works fine every time. But If I want to do C:, D:, & E:\ I can either run 3 scripts of the same code with separate drives, or alter the query in the single script to use C "OR" D but either way tends to hit the quota limit and doesn't reliably catch the create event.
-
Nilpo about 10 years@Dss Leave off this part TargetInstance.GroupComponent='Win32_Directory.Name=""C:\\\\""'" altogether. Then use an If statement to check each instance for the paths you want to monitor. Your query should just be "SELECT * FROM __InstanceCreationEvent WITHIN 10 WHERE TargetInstance ISA 'CIM_DirectoryContainsFile'". That said, checking multiple drives could cause memory issues depending upon how much space is used.
-
Dss about 10 years@Nilpo Thanks I'll try that
-
Dss about 10 years@Nilpo Ok Tried your way.. immediately hits the quota violation upon startup. I think monitoring so many events without a clause just overloads it. It only seems to work with a single drive when I use the TargetInstance.GroupComponent='Win32_Directory.Name=""C:\\\\""'". I'll have to try a purely vbs method to do more than one.
-
Nilpo about 10 years@Dss Are these large drives? Maybe it's time to find a third-party COM component that can monitor new files more efficiently than WMI.
-
Dss about 10 years@Nilpo Yes these are very large drives.. 2 of them are network drives mapped to a drive letter. They all work fine on their own.. but any combination or attempt to monitor more than one or a larger recordset seems to bring wmi to its knees. I created a simple vbs that works fine. Thanks!