How to monitor a Windows folder for new files and take action

Contents

Files are in a state of constant change on any operating system. Sometimes they create, sometimes they are removed, sometimes they change, and those are all normal things an operating system should do. Sometimes, when a file is changed, it can cause instability in another application that depends on it, how to change a port number in a properties file, a parameter in a deployment manifest or even correct the code in production without going through source control.

As part of the administration of these operating systems, engineers need a way to observe what happens to these critical files and take action when something happens. Enter the .NET Clase FileSystemWatcher y PowerShell.

In .NET y .NET Core, FileSystemWatcher is a class that lives in the System.IO namespace and monitor files. A PowerShell, This can be very helpful, especially when combined with other PowerShell functions.

Instantiation of FileSystemWatcher

Create an instance of this class in PowerShell by running $watcher = New-Object System.IO.FileSystemWatcher. Once i do, you should tell him which folder to look at. You can do this by setting the Path in the FileSystemWatcher object to the path of the folder you want to view. If you have a folder in Windows called WatchThisFolder below C:, you need to set FileSystemWatcher on that by running $watcher.Path="C:WatchThisFolder".

Because this class is also in .NET Core, you can do all of this on a Linux or Mac OS system in the same way that you would on a Windows system. As an example, if i had a folder on Ubuntu Linux called WatchThisFolder under your current user directory, should run $watcher.Path="/home/ubuntu/WatchThisFolder".

The rest of the code examples in this post work on either platform without any changes..

Event activation from FileSystemWatcher

Now that you have a new FileSystemWatcher object, you can take a look under the hood and try to find out. To view the specific types of file system events that FileSystemWatcher is observing, enter $watcher | Get-Member -MemberType Event. Get member shows everything contained in the object that happened to it and, when adding the MemberType filter, can see a certain category, in this circumstance, events.

Those events are:

  • Change
  • Created
  • Removed
  • Willing
  • Error
  • Renowned

When one or more of these FileSystemWatcher events is detected in the path that the object is configured to watch, the observing object generates an external event, for which you can set actions.

Now that the observer object knows what to look at and you know what events it is observing, you need to configure it to raise an event when an action is detected. Do this running $watcher.EnableRaisingEvents = $true. Think of this flag as a power switch / off for $watcher : If the switch is off, nothing will happen if changes are made. Additionally you can tell it to look at the files and folders nested below the set in the path by changing the Include subdirectories the flag to true the same way you did the EnableRaisingEvents flag.

Definition of actions to take

Once the observer object is configured, you need to give it an action to take once that change is detected. this can be as simple as writing to a system log, or as drastic as triggering an instance replacement with a clean extraction of the source code. To start, you must set an action block in your code. Here's one that you only type on the console:

$action = {
    $path = $event.SourceEventArgs.FullPath
    $name = $event.SourceEventArgs.Name
    $changetype = $event.SourceEventArgs.ChangeType
    Write-Host "File $name at path $path was $changetype at $(get-date)"
}

You can see that this code is extracting variables from the event using the $event variable, which is created automatically when the observer object creates the event. As soon as the event ends, the variable also ends, which means you will only have data relevant to that event.

Using the Register-ObjectEvent

Then, you have FileSystemWatcher set up and you have actions you want to take whenever something happens. At this time, these two are separated and do not know each other. So that they work together, you must register the actions with the event. PowerShell has a full cmdlet for this: the Register-ObjectEvent cmdlet. To use Register-ObjectEvent, three things must happen to him:

  • The FileSystemWatcher object
  • The type of event to trigger actions on
  • The actions you previously defined

If you have configured everything the same way as previously listed, it will look like this: Register-ObjectEvent $watcher 'Event Action' -Action $action. ‘Event Action’ can be overridden with any event from the FileSystemWatcher, but this will be a good demonstration.

Testing it

Now you can try everything. In this section, will create a new file in the specified directory, you will see the event action, later disable and unregister the event.

To create a new file and fire the event, run the next line in PowerShell. This is on Ubuntu Linux, but if you are following it on windows, replace / beginning / ubuntu / with C: and / with .

New-Item -Path "/home/ubuntu/WatchThisFolder/newFile" -ItemType File

As soon as I enter that, the event fires and the action fires.

File newFile at path /home/ubuntu/WatchThisFolder/newFile was Created at 09/26/2019 20:49:54

It fires every time you create a new file in that directory or anything nested below it, if you enabled the Include subdirectories flag. Now that you know that incrementing the event works, turn it off by running $watcher.EnableRaisingEvents = $false, later try to create a new file. The file should be created, but no event is displayed. This can be very useful if you are debugging and do not want to activate anything while working on the file system.

Once i'm done, run Get-EventSubscriber | Unregister-Event to unregister the event from the action. Now, even if the EnableRaisingEvents flag is true and the action occurs, the action will not fire.

Subscribe to our Newsletter

We will not send you SPAM mail. We hate it as much as you.