Im trying to use FileSystemWatcher to watch a file and check for changes, when a change occurs it should run aa command, this works when im saving the file in notepad, however not from the actual application that is making the log file.
Ive seen posts in the past saying that it may be due to the application creating a copy of the log with the new data added then deletes the original and renames the copy, so I tried looking for delete, creation and rename events and still nothing.
This is the class that I've been using, it does have to be a derived class of FileSystemWatcher as there is other functionality that is to be included which is out of the scope of this question.
class LogWatcher : System.IO.FileSystemWatcher {
[System.Management.Automation.Job[]] $Event
[string] $LogName = 'Endpointlog.txt'
[string] $LogFolder = ('C:\Users\' + $env:USERNAME + '\AppData\Roaming\<pathtologfolder>')
LogWatcher () : base($this.LogFolder, $this.LogName) {
$this.Event = (new-object System.Management.Automation.Job[] 4)
$this.EnableRaisingEvents = $true;
$fsaction = {
param (
[System.Object] $sender,
[System.IO.FileSystemEventArgs] $e
)
$sender | fl
$e | fl
}
$rnaction = {
param (
[System.Object] $sender,
[System.IO.renamedEventArgs] $e
)
$sender | fl
$e | fl
}
$this.NotifyFilter =[System.IO.NotifyFilters]::Attributes, [System.IO.NotifyFilters]::CreationTime, [System.IO.NotifyFilters]::DirectoryName, [System.IO.NotifyFilters]::FileName, [System.IO.NotifyFilters]::LastAccess, [System.IO.NotifyFilters]::LastWrite, [System.IO.NotifyFilters]::Security, [System.IO.NotifyFilters]::Size
$this.Event[0] = register-ObjectEvent -InputObject $this -EventName changed -Action $fsaction
$this.Event[1] = register-ObjectEvent -InputObject $this -EventName created -Action $fsaction
$this.Event[2] = register-ObjectEvent -InputObject $this -EventName deleted -Action $fsaction
$this.Event[3] = register-ObjectEvent -InputObject $this -EventName renamed -Action $rnaction
}
}
And initialising it as.
$lw = [LogWatcher]::new();
The log file is updated every couple seconds so I would expect that $lw.Event to show at least one Job that is running and not Not Started however I can still only get one Job to change and that is when I open the log and save it directly and as a note, notepad asks to save as rather than just save as normal which does still make me think that its being copied, deleted and copy renamed.
Is there any way that i can get any event to fire when the those switches are made?
The Action block of your events run in a different scope and all output produced in them is captured in the
.Outputproperty of eachPSEventJob. For example, the.Outputon index0would show you all output captured byChangedraised events, index1forCreatedevents and so on:If you're troubleshooting however, it's much easier to use
Out-Host, then the output is sent directly to the console (Write-Hostwould work too):Worth noting here, in PowerShell,
$Senderand$EventArgsare automatic variables, you don't need to declare them.I made a few changes to your class too that might help you simplify things:
Now for testing, this should work fine in both, Windows PowerShell 5.1 and PowerShell 7+. You should see all events being raised.