Monitor a folder for any file changes within it

Monitor a folder for any file changes within it.  I need to be able to view a report as needed.  The report should show a date/time stamp for each time any file within that folder changes so that I can easily see the lineage. This is on a Windows 2016 computer and I should be able to access the report locally at least.

Suggestions for such a thing are greatly appreciated.
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Martin MillerCTOCommented:
You can setup a file watcher script in powershell. Alternatively, NodeJS has a native file watcher capability you can use to trigger and then script in the email action.
Give a try for this example : You can find your logs into the folder %AppData% as Nameofyourfolder.log
Option Explicit
If AppPrevInstance() Then   
	MsgBox "There is an existing instance !" & VbCrLF &_
	CommandLineLike(WScript.ScriptName),VbExclamation,"There is an existing instance !"   
	Call MonitorFolder()
end if
Sub MonitorFolder()
	Dim fso,Message,Message2,Msg,intInterval,strDrive,strFolder,strComputer,objWMIService,strQuery
	Dim colEvents,objEvent,objTargetInst,objPrevInst,objProperty,ws,LOG_FILE_PATH,LogFile,PathFolder,MonTableau
	Set fso = CreateObject("Scripting.FileSystemObject")
	Set ws = CreateObject("WScript.Shell")
	strComputer = "." 
	PathFolder = Browse4Folder
	MonTableau = Split(PathFolder,"\")
	LogFile = MonTableau(UBound(MonTableau)) & ".log"
	LOG_FILE_Path = ws.ExpandEnvironmentStrings("%AppData%") & "\" & LogFile
	intInterval = "2"
	PathFolder = Split(fso.GetAbsolutePathName(PathFolder),":")
	strDrive  = PathFolder(0) & ":"
	strFolder = Replace(PathFolder(1), "\", "\\")
	If Right(strFolder, 2) <> "\\" Then strFolder = strFolder & "\\"
'Connecting to WMI
	Set objWMIService = GetObject( "winmgmts:" &_ 
	"{impersonationLevel=impersonate}!\\" &_ 
	strComputer & "\root\cimv2" )
'The query string
	strQuery =  _
	"Select * From __InstanceOperationEvent" _
	& " Within " & intInterval _
	& " Where Targetinstance Isa 'CIM_DataFile'" _
	& " And TargetInstance.Drive='" & strDrive & "'"_
	& " And TargetInstance.path='" & strFolder & "'"
'Run Query
	Set colEvents = _
		Set objEvent = colEvents.NextEvent()
		Set objTargetInst = objEvent.TargetInstance
		Select Case objEvent.path_.Class 
'If this is the case of file creation or deletion event and display just the file name
		Case "__InstanceCreationEvent" 
			Message = DblQuote(objTargetInst.Name) & " is created !"
			Message2 = String(10,"*") & Now & String(10,"*") & vbCrLf & Message & vbCrLf & String(70,"*")
			Call Log(LOG_FILE_Path,Message2)
'MsgBox Message2,VbInformation,Message
		Case "__InstanceDeletionEvent" 
			Message = DblQuote(objTargetInst.Name) & " is deleted !"
			Message2 = String(10,"*") & Now & String(10,"*") & vbCrLf & Message & vbCrLf & String(70,"*")
			Call Log(LOG_FILE_Path,Message2)
'MsgBox Message2,VbInformation,Message
'If this is the case of the modification of the file, compare the property values of the target and the previous instance
'and view the properties that have been changed as the size and LastModified
		Case "__InstanceModificationEvent" 
			Set objPrevInst = objEvent.PreviousInstance
			For Each objProperty In objTargetInst.Properties_
				If objProperty.Value <> _
				objPrevInst.Properties_(objProperty.Name) Then
				Message = "modified file :        " & vbCrLf &_
				objTargetInst.Name & vbCrLf &_
				"Property :       "_
				& objProperty.Name & vbCrLf &_
				"Last Value : "_
				& objPrevInst.Properties_(objProperty.Name) & vbCrLf &_
				"New value :      " _
				& objProperty.Value
				Message2 = String(10,"*") & Now & String(10,"*") & vbCrLf & Message & vbCrLf & String(70,"*")
				Call Log(LOG_FILE_Path,Message2)
'MsgBox Message,64,DblQuote(objTargetInst.Name)
			End If    
	End Select 
End Sub
Sub Log(strLogFilePathFolder,strLogContent)
Const APPEND = 8
Dim objFso,objLogFile
Set objFso = CreateObject("Scripting.FileSystemObject")
If Not objFso.FileExists(strLogFilePathFolder) Then objFso.CreateTextFile(strLogFilePathFolder, True).Close
Set objLogFile = objFso.OpenTextFile(strLogFilePathFolder,APPEND)
objLogFile.WriteLine strLogContent
End Sub 
'Checks whether a script with the same name as this script is already running
Function AppPrevInstance()   
With GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\.\root\cimv2")   
	With .ExecQuery("SELECT * FROM Win32_Process WHERE CommandLine LIKE " & CommandLineLike(WScript.ScriptFullName) & _
		" AND CommandLine LIKE '%WScript%' OR CommandLine LIKE '%cscript%'")   
		AppPrevInstance = (.Count > 1)   
	End With   
End With   
End Function       
Function CommandLineLike(ProcessPath)   
ProcessPath = Replace(ProcessPath, "\", "\\")   
CommandLineLike = "'%" & ProcessPath & "%'"   
End Function
'Function to add the double quotes into a variable
Function DblQuote(Str)
DblQuote = Chr(34) & Str & Chr(34)
End Function
Function Browse4Folder()
Dim ws,objFolder,Copyright
Copyright = "  [ by Hackoo 2015 ]"
Set ws = CreateObject("Shell.Application")
Set objFolder = ws.BrowseForFolder(0,"Choose a folder for monitoring it"_
& Copyright,1,"c:\Programs")
If objFolder Is Nothing Then
End If
Browse4Folder = objFolder.self.path
end Function

Open in new window

frugalmuleAuthor Commented:
I installed NodeJS.  When you open it, it shows a command prompt.
Cloud Class® Course: Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

frugalmuleAuthor Commented:
The folder that I am needing to monitor, as well as the files and folders within it is C:\Program Files\AmiBroker
Martin MillerCTOCommented:
WRT to "When you open it, it shows a command prompt.", yes this is true,  you need script to be loaded to do the file watch, this is not difficult, but, does require learning about this, maybe a 30 minute exercise.
Joseph HornseyPresident and JanitorCommented:
You can use built in auditing in Windows.

Go to your Local Security Policy (or Group Policy, if in a domain).

Local Policies > Audit Policies > Turn on Success and Failure for "Audit object access".

On the C:\Program Files\AmiBroker folder, go to Properties > Security and click "Advanced".  Set your auditing options on the "Auditing" tab.

Stuff shows up in Event Viewer.
Joseph's post about auditing is a means of notification.
What is the underlying need, do you merely need to know which file and when a change, do you need the record of the change?

A document management system, that will control access and includes versioning
frugalmuleAuthor Commented:
Joseph and Arnold,

It sounds like a good plan to me also to use built-in auditing for this.  I just want to know when the last change occurred.  Keeping up with version changes would be nice but is not a must-have.

I need to know what the last modifications were to files found in the C:\Program Files\AmiBroker folder.

Unfortunately, I am lost at the last step. What then?

I don't see exactly what to do next?
searching the event log and then looking at it for the content, I think powershell and others can pull and check the messages.

A more proactive that reads the event logs and creates the record that then can be searched, i.e. events for C:\Program Files\AmiBroker
and it ill return the file, date and who changed it, splunk I think catalogues ...

much depend on what resources you have.

Audit does not provide for versioning, i.e. you get notice that C:\Program Files\AmiBroker\somefile.doc was modified by me.
Backup if exist will be to the version prior to the change. if multiple people made changes, between the backups, the only thing that will be seen is the last saved change.

on the share, security settings, advanced, auditing, you enabled auditing, did you specify a specific group or all who access this folder will have the security event updated ......

depending on the activity and the setting for the size of the event log file, the data might not be there long enough for you to have the opportunity to review...
frugalmuleAuthor Commented:
ouch, not good.  Perhaps then, I need to be looking for a version control product that will monitor that folder out-of-the-box.
Joe Winograd, Fellow&MVEDeveloperCommented:
Hi fm,
I was intrigued by this question and started designing a program to do it. After a short while playing with some ideas, I decided to do a web search ("monitor folder for changes") to see if there are any "competitors" out there before going any further. I ran across this article:
10 Tools to Monitor Files and Folders for Changes in Real Time

I'm wondering if you've tried any of the programs in that article, or any others.

One other thought. I'm a big fan of the AutoHotkey language and likely would have written the program in it. Another web search turned up this very interesting AutoHotkey script:

Note these comments in the script, which document the folder/file changes that it can monitor:

;     ReadDirectoryChangesW
;     FILE_NOTIFY_CHANGE_FILE_NAME   = 1   (0x00000001) : Notify about renaming, creating, or deleting a file.
;     FILE_NOTIFY_CHANGE_DIR_NAME    = 2   (0x00000002) : Notify about creating or deleting a directory.
;     FILE_NOTIFY_CHANGE_ATTRIBUTES  = 4   (0x00000004) : Notify about attribute changes.
;     FILE_NOTIFY_CHANGE_SIZE        = 8   (0x00000008) : Notify about any file-size change.
;     FILE_NOTIFY_CHANGE_LAST_WRITE  = 16  (0x00000010) : Notify about any change to the last write-time of files.
;     FILE_NOTIFY_CHANGE_LAST_ACCESS = 32  (0x00000020) : Notify about any change to the last access time of files.
;     FILE_NOTIFY_CHANGE_CREATION    = 64  (0x00000040) : Notify about any change to the creation time of files.
;     FILE_NOTIFY_CHANGE_SECURITY    = 256 (0x00000100) : Notify about any security-descriptor change.
;     FILE_ACTION_ADDED              = 1   (0x00000001) : The file was added to the directory.
;     FILE_ACTION_REMOVED            = 2   (0x00000002) : The file was removed from the directory.
;     FILE_ACTION_MODIFIED           = 3   (0x00000003) : The file was modified.
;     FILE_ACTION_RENAMED            = 4   (0x00000004) : The file was renamed (not defined by Microsoft).
;     FILE_ACTION_RENAMED_OLD_NAME   = 4   (0x00000004) : The file was renamed and this is the old name.
;     FILE_ACTION_RENAMED_NEW_NAME   = 5   (0x00000005) : The file was renamed and this is the new name.
;     GetOverlappedResult  
;     CreateFile           
;     FILE_FLAG_BACKUP_SEMANTICS     = 0x02000000
;     FILE_FLAG_OVERLAPPED           = 0x40000000

Open in new window

Looks like a great starting point...maybe even an end point. :)

Regards, Joe

Update: I've been playing with the AutoHotkey WatchFolder script for the last hour — looks very good! I used the sample test script posted there, but modified the A_TickCount column (which is the number of milliseconds since the computer was rebooted) to a date/time stamp in YYYY-MM-DD_hh:mm:ss format. Here's what its output screen looks like after watching one of my temp folders:

WatchedFolder test
While the sample script displays the info in a listview window, it would be easy to change it to create a report/logfile. Great stuff!
frugalmuleAuthor Commented:
Your last screenshot is exactly what I need I think.  I just don't want to do the scripting to get there. I was hoping for something already written where I could just select the folder I want to monitor, and be able to evaluate how things changed over time. Most importantly, when the last file changed and which file it was. I am sure I will add major exclusions also over time, so something a little more turnkey is needed. Thanks for the list also, I will look through that.
Joe Winograd, Fellow&MVEDeveloperCommented:
> Your last screenshot is exactly what I need I think.

Glad to hear it (I'll leave in the YYYY-MM-DD_hh:mm:ss column).

> I just don't want to do the scripting to get there. I was hoping for something already written where I could just select the folder I want to monitor, and be able to evaluate how things changed over time.

No problem. The sample test script already prompts you for a folder. Here's what the opening dialog looks like:

WatchFolder select folder
I can even hard-code the C:\Program Files\AmiBroker folder if you prefer. I can also compile it into a stand-alone executable (an EXE file, as discussed in my AutoHotkey article) so that you don't have to install AutoHotkey — you'll just run the executable.

> Most importantly, when the last file changed and which file it was.

OK, it already does that.

> I am sure I will add major exclusions also over time

I don't know what you mean by "add major exclusions" — please explain.

> something a little more turnkey is needed

As mentioned above, it can be completely turnkey.

Regards, Joe
frugalmuleAuthor Commented:
Being able to select the folder would be fantastic.  How do I put exclude particular files and folders from monitoring?
Joe Winograd, Fellow&MVEDeveloperCommented:
> Being able to select the folder would be fantastic.

The sample script already allows you to select one folder and, optionally, include its subfolders, which is the "In Sub-Tree" check-box in the screenshot above. I changed that to say "Include subfolders" and moved it to right underneath the "Select a folder..." box. I also added an Exit button; changed the icon from the default AutoHotkey "H" to a folder icon (from the built-in shell32.dll); and changed the name from "Watch Folder" to "Monitor Folder". So, the new opening dialog looks like this:

> How do I put exclude particular files and folders from monitoring?

You exclude root folders by simply not including them — as it is now, you cannot exclude specific subfolders when you tick the "Include subfolders" checkbox. Also as it is now, you cannot exclude particular files. That is very doable, but would take this from a Question to a Gig. :)  Regards, Joe
frugalmuleAuthor Commented:
Ok, where do I download this from?
Joe Winograd, Fellow&MVEDeveloperCommented:
I'll compile the script for you using the AutoHotkey compiler (and will leave in the YYYY-MM-DD_hh:mm:ss change and the other UI changes). But Experts Exchange doesn't allow uploading EXE files, so I'll send you (and anyone else who is interested) via an EE message a link to download it from my domain. Regards, Joe
Joe Winograd, Fellow&MVEDeveloperCommented:
For anyone who is interested, frugalmule and I have been communicating via PM to nail down the specs for the program. Based on his particular requirements, along with some of mine, the program does everything mentioned earlier in this thread, plus the following:

• Changed the action when clicking the red X in the upper right ("Close") to exit the program, i.e., the same as clicking the Exit button in the main window. In both cases, there's a "Do you really want to exit?" dialog so that an accidental click won't result in exiting.

• Removed the taskbar icon (unless you click the Minimize button).

• Provided an option to remove the system tray icon. When removed, the way to activate the GUI is via a hotkey, currently configured as Shift+Ctrl+F12 (can also be used when the tray icon is present).

• Added the #SingleInstance force directive so that re-running the script automatically replaces the running script (no more "older instance of this script is already running" message).

• Added a "Hide" button between the "Clear" and "Exit" buttons to hide the GUI after it is used.

• Removed the "Monitor these changes" check-boxes and enabled all of them, i.e., Files, Folders, Attributes, Size, Last Write, Last Access, Creation, Security.

• Added a logfile/report feature. It writes each entry that goes to the GUI window into a plain text file. It creates an AppData subfolder (c:\Users\<username>\AppData\Roaming\MonitorFolder\) and stores the logfile in it with a file name that contains a date-time stamp, such as MonitorFolder_Logfile_2018-03-20_17.11.07.txt (i.e.,

• Added a prompt when exiting that shows the full file path of the logfile and asks if you want to open it now. If you hit the Yes button, it opens the logfile in whatever program owns the TXT file type; if you hit the No button, it just exits.

• Added a tray tip when hovering on the system tray that shows the program's version and build, the folder being monitored, and whether or not subfolders are included. Looks like this:

MonitorFolder traytip
• Changed the system tray right-click/context menu to have three choices: (1) Continue Running (the default, so that an accidental double-click on it does nothing); (2) Open (opens the main window GUI); (3) Exit (exits the program, but does not prompt about the logfile as the Close and Exit buttons in the GUI do). Looks like this:

MonitorFolder context menu
• Added an End-User License Agreement (EULA) that must be agreed with before using the program.

On the to-do list:

• Add an email feature to send the logfile daily (or maybe on a user-specified time interval, and maybe on demand via a button in the GUI and/or context menu).

The new dialog looks like this (but clicking the email button results in a message that says email is not yet implemented):

MonitorFolder GUI
I compiled the script using the AutoHotkey compiler into a stand-alone executable. But, as I mentioned earlier, Experts Exchange doesn't allow uploading EXE files, so I'll send anyone who requests it (via an EE PM to me) a link to download it from my domain. Regards, Joe

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
frugalmuleAuthor Commented:
This is really well done. It's simple and exactly what I needed to know when my developer is in my VM working and when he isn't.
It's nice to be able to see if they did anything on a particular day.
Joe Winograd, Fellow&MVEDeveloperCommented:
Glad to hear it...thanks for the compliments. Regards, Joe
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Windows OS

From novice to tech pro — start learning today.

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.