Powershell : FileSystemWatcher for filename change - powershell

I tried using this code to monitor filename changes on our fileserver. But I only want to trigger the event when the extension changes.
Any suggentions?
### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "E:\"
# $watcher.Filter = "*.*"
$watcher.IncludeSubdirectories = $true
$watcher.EnableRaisingEvents = $true
$action = { $path = $Event.SourceEventArgs.FullPath
$changeType = $Event.SourceEventArgs.ChangeType
$Name = $Event.SourceEventArgs.Name
$logline = "$(Get-Date), $changeType, $path, $name"
Add-content "E:\log.txt" -value $logline
}
Register-ObjectEvent $watcher "Renamed" -Action $action
while ($true) {sleep 5}

Set the NotifyFilter property in the $watcher variable to FileName only.
$watcher.NotifyFilter = 'FileName'
Now the action will only trigger for file name changes.

Related

How to make a io.systemfileswatcher run indefinitely

I have a script that calls two io.systemfile watchers which I would like to run 24x7 so that it can detect data that needs to be processed and automatically hand it off to a script that processes it (and uploads the result to the network):
Function Report1Watcher{
param ($folder)
$filter = "*vac*.csv"
$watcher = New-Object IO.FileSystemWatcher $folder, $filter -Property #{
IncludeSubdirectories = $true
EnableRaisingEvents = $true
InternalBufferSize = 65536
}
Write-Host "Watching $folder for creation of $filter files..."
$changeAction = {
$path = $Event.SourceEventArgs.FullPath
$name = $Event.SourceEventArgs.Name
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
$Actionpath = Split-Path $Path
write-host $Actionpath " Ready for Report1"
Report1 $Actionpath
write-host $Actionpath " Report1 Generated"
}
Register-ObjectEvent $Watcher -EventName "Created" -Action $changeAction
}
Function Report2Watcher{
param ($folder)
$filter = "*4.4*"
$watcher = New-Object IO.FileSystemWatcher $folder, $filter -Property #{
IncludeSubdirectories = $true
EnableRaisingEvents = $true
InternalBufferSize = 65536
}
Write-Host "Watching $folder for creation of $filter files..."
$changeAction = {
$path = $Event.SourceEventArgs.FullPath
$name = $Event.SourceEventArgs.Name
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
$Actionpath = Split-Path $Path
$Actionpath = Split-Path $Actionpath
write-host $Actionpath " Ready for Report2"
Report2 $Actionpath
write-host "Report2 Generated"
}
Register-ObjectEvent $Watcher -EventName "Created" -Action $changeAction
}
Function Watchmaster{
Report1Watcher $Testdir
Report2Watcher $Testdir
}
Watchmaster
I am thinking of turning it into a windows service, but would it be able to run 24x7 as is? I'm not sure where I could add an infinite loop without creating infinite io.systemfilewatchers. I know as a PS script that powershell would need to constantly be running. But if I created a batch file that runs this and set it up as a service with nssm would this accomplish what I need?

Powershell: FileSystemWatcher filter option - Not working.

I would like to watch out for files having name like "today's date then 6digits then _ABC_XYZ.csv". For e.g. if today's date is 20181011 then the file should be the name: 20181011123456_ABC_XYZ.csv. Below is my code:
$DateStr = $Date.ToString("yyyyMMdd")
### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "E:\\Sid\\source"
$watcher.Filter = $DateStr + "\d\d\d\d\d\d*_Recon_ForeignExchange.csv"
$watcher.IncludeSubdirectories = $true
$watcher.EnableRaisingEvents = $true
### DEFINE ACTIONS AFTER AN EVENT IS DETECTED
$action = { $path = $Event.SourceEventArgs.FullPath
$changeType = $Event.SourceEventArgs.ChangeType
$logline = "$(Get-Date), $changeType, $path"
Add-content "D:\log.txt" -value $logline
}
### DECIDE WHICH EVENTS SHOULD BE WATCHED
Register-ObjectEvent $watcher "Created" -Action $action
Register-ObjectEvent $watcher "Changed" -Action $action
Register-ObjectEvent $watcher "Deleted" -Action $action
Register-ObjectEvent $watcher "Renamed" -Action $action
while ($true) {sleep 5}
My Queries:
Its seems that the $watcher.filter is not working as it's taking files other than the one given in the filter as well.
Also I would like to watch 2 folders at a time as the file can come in any of the folders. How do I achieve this?
As #Theo pointed out, the Filter property does not support regex. Only path wildcards are allowed.
You will have to use a simpler wildcard in your filter:
# rough wildcard filter
$watcher.Filter = "*_Recon_ForeignExchange.csv"
..and then perform a more specific (regex) check in your handler:
$action = {
$path = $Event.SourceEventArgs.FullPath
# check if the file name has the desired format
if ((Split-Path $path -Leaf) -match ($DateStr + "\d\d\d\d\d\d*_Recon_ForeignExchange.csv"))
$changeType = $Event.SourceEventArgs.ChangeType
$logline = "$(Get-Date), $changeType, $path"
Add-content "D:\log.txt" -value $logline
}
}
As for the other directory, #vrdse already pointed out that you're going to need a 2nd watcher for that.

Calculate created time between same file in 2 folders

I need to measure the time of a SAME file that is created in 2 different folders.
Example: folder1\test.txt and folder2\test.txt
Use Get-Date for each file, and the seconds difference between those.
The script need to keep running and creating a log for each file, containing the file name and the time difference in seconds
###start-process PowerShell.exe -arg C:\Users\Smap\Documents\logs\StartMonitoring.ps1 -WindowStyle Hidden
### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
$watcherStart = New-Object System.IO.FileSystemWatcher
$watcherEnd = New-Object System.IO.FileSystemWatcher
$watcherStart.Path = "C:\Users\Smap\Desktop\MATHEUS\entrada"
$watcherEnd.Path = "C:\Users\Smap\Desktop\MATHEUS\saida"
$watcherStart.Filter = "*.*"
$watcherEnd.Filter = "*.*"
### $watcherStart.IncludeSubdirectories = $true
$watcherStart.EnableRaisingEvents = $true
$watcherEnd.EnableRaisingEvents = $true
### DEFINE ACTIONS AFTER AN EVENT IS DETECTED
$actionStart = { $namefileStart = $Event.SourceEventArgs.Name
$changeTypeStart = $Event.SourceEventArgs.ChangeType
$timeStart = Get-Date
}
$actionEnd = { $filepath = "C:\Users\Smap\Desktop\MATHEUS\log\log " + ($namefileStart) + ".txt"
###$filepath = "C:\Users\Smap\Desktop\MATHEUS\log\log.txt"
$namefileEnd = $Event.SourceEventArgs.Name
$changeTypeEnd = $Event.SourceEventArgs.ChangeType
$timeEnd = Get-Date
if ($namefileStart -eq $namefileEnd) {
$timeDiff = (NEW-TIMESPAN -Start $timeStart -End $timeEnd)
$logline = "$namefileStart, $namefileEnd, $timeStart, $timeEnd, $timeDiff"
Add-content $filepath -value $logline
}
}
### DECIDE WHICH EVENTS SHOULD BE WATCHED
Register-ObjectEvent $watcherStart "Created" -Action $actionStart
Register-ObjectEvent $watcherEnd "Created" -Action $actionEnd
###Register-ObjectEvent $watcher "Changed" -Action $action
###Register-ObjectEvent $watcher "Deleted" -Action $action
###Register-ObjectEvent $watcher "Renamed" -Action $action
while ($true) {sleep 5}`

PowerShell FileSystemWatcher exit while ($true)

I need this script to loop until it does the action but I can't seem to break the loop.
# SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "C:\TransX\InputTriggers\"
$watcher.Filter = "IVANS_TRIGGER_FILE.trig"
$watcher.IncludeSubdirectories = $false
$watcher.EnableRaisingEvents = $true
# DEFINE ACTIONS AFTER AN EVENT IS DETECTED
$action = {
$path = $Event.SourceEventArgs.FullPath
$changeType = $Event.SourceEventArgs.ChangeType
$logline = "$(Get-Date), $changeType, Ivans File Arrived"
Add-Content "C:\TransX\InputTriggers\ProcessLog.txt" -Value $logline
Start-Process C:\TransX\Transxdl.bat
Remove-Item C:\TransX\InputTriggers\IVANS_TRIGGER_FILE.trig
break
}
# DECIDE WHICH EVENTS SHOULD BE WATCHED
Register-ObjectEvent $watcher "Created" -Action $action
#Register-ObjectEvent $watcher "Changed" -Action $action
#Register-ObjectEvent $watcher "Deleted" -Action $stopScript
Register-ObjectEvent $watcher "Renamed" -Action $action
while ($true) {sleep 5}
The break command in the $action isn't working.
BREAK and CONTINUE will only work this way when used inside a loop, your action is not in the loop itself.
What you could try, is using a variable like $ContinueWatching for your loop and switch it from the Action.
Example:
$ContinueWatching = $true
$Action = {
# <Your code here>
# <Remove break>
# StopWatching and Exit Script
$global:ContinueWatching = $false
}
While ($ContinueWatching) {
Start-Sleep -s 1
}

Difference action for different files

I want to monitor new files created in a folder.
When this happens I want to launch a batch file (in the example below I just write a line in a log file).
I don't know why this doesn't work.
My code is:
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "D:\"
$watcher.Filter = "*.*"
$watcher.IncludeSubdirectories = $true
$watcher.EnableRaisingEvents = $true
$action = {
$path = $Event.SourceEventArgs.FullPath
$changeType = $Event.SourceEventArgs.ChangeType
$logline = "$(Get-Date), $changeType, $path"
if ($file.Name -like "Apertura") {
Add-Content "C:\Users\F701845\Desktop\Apertura.txt" -Value $logline
} else {
Add-Content "C:\Users\F701845\Desktop\TestNO.txt" -Value $logline
}
}
Register-ObjectEvent $watcher "Created" -Action $action
while ($true) {sleep 5}
Well this one is easy, you are using a variable that is empty in your IF/ELSE.
$path and $changeType are derived from $Event but $file is not existing at all.
First take a look at what you have and you will see that you might be able to use in this case: $Event.SourceEventArgs.Name.
$Event.SourceEventArgs | Get-Member
bool Equals(System.Object obj)
int GetHashCode()
type GetType()
string ToString()
System.IO.WatcherChangeTypes ChangeType {get;}
string FullPath {get;}
string Name {get;}
While it does work, it still looks for files called exactly Apertura meaning Apertura.txt wont work, i would recommend using something like Apertura.* if you do not know the extension.
Example Code:
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "C:\test\"
$watcher.Filter = "*.*"
$watcher.IncludeSubdirectories = $true
$watcher.EnableRaisingEvents = $true
$action = {
$path = $Event.SourceEventArgs.FullPath
$changeType = $Event.SourceEventArgs.ChangeType
$file = $Event.SourceEventArgs.Name #get filename from Event data
$logline = "$(Get-Date), $changeType, $path"
if ($file -like "Apertura.*") { #removed the .Name and added .*
Add-Content "C:\Users\username\Desktop\Apertura.txt" -Value $logline
} else {
Add-Content "C:\Users\username\Desktop\TestNO.txt" -Value $logline
}
}
Register-ObjectEvent $watcher "Created" -Action $action
while ($true) {sleep 5}
$watcher.Dispose() #can be used to dispose the System.IO.FileSystemWatcher