I have the context of a task right before me: I want to create a Scheduled Task on WinServer2012 which is triggered by events generated from a file's lastwrite date changing.
I've got Powershell code in my hands (thanks to https://gallery.technet.microsoft.com/scriptcenter/Powershell-FileSystemWatche-dfd7084b ) which monitors for such events and calls-back a specific action, e.g.:
$folder = 'c:\temp' # Enter the root path you want to monitor.
$filter = 'test.txt' # You can enter a wildcard filter here.
$fsw = New-Object IO.FileSystemWatcher $folder, $filter -Property @{IncludeSubdirectories = $false;NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'}
Register-ObjectEvent $fsw Changed -SourceIdentifier FileChanged -Action {
$name = $Event.SourceEventArgs.Name
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
Write-Host "The file '$name' was $changeType at $timeStamp" -fore white
}
It seems this code creates a mechanism for producing such events and also registers a callback for responding to such events. Is that a correct understanding? Or are the events produced regardless? When I review the documentation for the FileSystemWatcher class, https://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher(v=vs.110).aspx , it appears that file change notifications are present without an instantiation of this class. Are notifications different from events? That class documentation says it monitors notifications and raises events. So that suggests the events are not present unless this class is instantiated. And it suggests that notifications are different from events.
In the Task Scheduler utility, I can create a task which is triggered on events and I can use the 3 fields: Log, Source and Event ID to indentify which event I want to trigger on. Perusing the Log choices, I see some resemblance to the variations of event logs available in the Event Viewer utility. Is it the case that all events are, by definition, sent to a particular log?
How would I determine what the different Log, Source and Event IDs that are available and to what they refer? Any documentation?
Is there a connection between the Powershell code and what I could configured for a trigger in Task Scheduler? Perhaps the trigger could not be made so specific as to monitor a single file for a LastWrite change and the task would be called too frequently on all sorts of file system events. It may be the best solution to the task I have at hand is to run the powershell code at boot up, however, I really am seeking a deeper understanding of how events work.
Thanks for your help.
Chris Lewis - Microsoft Premier Support provides this excellent answer:
Hi Kevin,
I’ve included your post and answered the questions inline in bold. Please do let me know if you have any further questions or if anything I said needs to be cleared up:
It seems this code creates a mechanism for producing such events and also registers a callback for responding to such events. Is that a correct understanding? Or are the events produced regardless?
The events referred to in this context on delegate invocations coming from a .NET object. Here’s some general documentation on that: https://msdn.microsoft.com/en-us/library/edzehd2t(v=vs.110).aspx. If there aren’t any delegates subscribed, then the event won’t be raised. The object tin question is a FileSystemWatcher, which is essential a wrapper class that exposes most of the functionality of ReadDirectoryChanges. There are many, many caveats to its use and it is a best effort listener so missed events have to be expected. Here’s a couple of blog articles that I wrote in the past addressing its limitations and ways to and not to use it: https://blogs.msdn.microsoft.com/winsdk/2015/05/19/filesystemwatcher-follies/ https://blogs.msdn.microsoft.com/winsdk/2015/06/04/filesystemwatcher-fencingpart-1/ https://blogs.msdn.microsoft.com/winsdk/2015/09/15/filesystemwatcher-fencingpart-2/
When I review the documentation for the FileSystemWatcher class, https://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher(v=vs.110).aspx , it appears that file change notifications are present without an instantiation of this class. Are notifications different from events? That class documentation says it monitors notifications and raises events. So that suggests the events are not present unless this class is instantiated. And it suggests that notifications are different from events.
Yes, notifications and events are different Events in this context are still referring to the same thing as the above. Notifications are referring to data from the file system reporting changes to active subscribers of ReadDirectoryChanges. If there is no one subscribed or the kernel is busy (it’s best effort for this particular kind which is unusual in general for APIs), there will be no notification. Data will not be even generated in memory if there is no subscriber. Also, data will not be generated if the driver for the particular type of file system doesn’t support the IOctl necessary for that function to work, but all of them which I am aware of currently do.
In the Task Scheduler utility, I can create a task which is triggered on events and I can use the 3 fields: Log, Source and Event ID to identify which event I want to trigger on. Perusing the Log choices, I see some resemblance to the variations of event logs available in the Event Viewer utility. Is it the case that all events are, by definition, sent to a particular log?
Events like in the event viewer, which is what task scheduler uses, are completely unrelated to .NET events. Unfortunately, there are no events to reasonably trigger off for the purpose of tracking changes to a file (you could have change journaling perhaps write everything to the event log, but if you triggered off of that, you’d slow the system down dramatically as so many resources would be needed all the time for monitoring and checking changes by different processes unless you had an NTFS drive that had almost no activity other than the one file that you care about). You could have code running all the time that does the monitoring and then writes a specific event when it happens, and if you did that, you could trigger task scheduler to run off of that event.
How would I determine what the different Log, Source and Event IDs that are available and to what they refer? Any documentation on this?
**This information is available for a particular system using event log APIs. Sticking to C#/PowerShell, you can run code to get the ProviderMetadata. I was going to type some code out, but there’s actually a great answer to this particular question with lots of PowerShell code examples in this stackoverflow post: https://stackoverflow.com/questions/21012622/get-windows-event-provider-information **
Is there a connection between the Powershell code and what I could configured for a trigger in Task Scheduler? Perhaps the trigger could not be made so specific as to monitor a single file for a LastWrite change and the task would be called too frequently on all sorts of file system events. It may be the best solution to the task I have at hand is to run the powershell code at boot up, however, I really am seeking a deeper understanding of how events work.
No, there’s no connection between the Powershell code and task scheduler triggers. The other type of event trigger that you’ll often see people use with Powershell is WMI; you also do not want to use that. It will effectively just poll constantly in order to function which makes it horribly inefficient. Running code all the time is the best way to achieve this, and you either have to use change journals, which has file system type requirements and writing more of your own parsing code, or add polling and recovery capabilities to your implementation that uses FileSystemWatcher as described in the blog articles. However, that being said, there is often a potentially better integration point when folks try to use FileSystemWatcher to accomplish something if you also control the software changing the files.
Best Regards,
Chris
BTW - Chris was heading out on vacation and didn't have time to enter the answer here, but gave me permission to do so. Of course, he deserves the credit.