Powershell - how to start action after a FEW files have been created - powershell

i want to loop a powershell script that monitors if a few xml files were created in a folder. If there are at least 3 it should restart a program.
Here is what i got from the use nixda on here:
### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "C:\DVNAV\11842596\nav2016\2019"
$watcher.Filter = "*.xml*"
$watcher.IncludeSubdirectories = $false
$watcher.EnableRaisingEvents = $true
### DEFINE ACTIONS AFTER AN EVENT IS DETECTED
$action = { Stop-Process -name dvnav -force
Start-Sleep -Seconds 8
Start-Process -FilePath 'C:\Program Files (x86)\DVNAV.exe' -verb RunAs
}
### 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}
But i don't know how i can set the monitoring to multiple files not just one.

This should work for you. Don't Forget to unregister Events after using/testing!
#--------------------------------------------------
function Stop-EventWatcher {
#--------------------------------------------------
# To stop the monitoring, run the following commands:
Unregister-Event FileCreated
}
$folderToWatch = 'C:\DVNAV\11842596\nav2016\2019'
$filter = '*.xml'
$script:counter = 0
# In the following line, you can change 'IncludeSubdirectories to $true if required.
$fsw = New-Object IO.FileSystemWatcher
$fsw.Path = $folderToWatch
$fsw.IncludeSubdirectories = $false
$fsw.EnableRaisingEvents = $true
$scriptBlock = {
$message = $event.MessageData # message data is how we pass in an argument to the event script block
$name = $Event.SourceEventArgs.Name
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
$script:counter++
if( $script:counter -eq 3 ) {
$script:counter = 0
# do special action here!
}
}
# Here, the event ist registered. You need only subscribe to events that you need:
Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -MessageData 'Hello' -Action $scriptBlock

Related

Powershell script not firing Register-ObjectEvent

I have the below script for folder watcher:
### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "C:\inetpub\wwwroot\exports\"
$watcher.Filter = "*.*"
$watcher.IncludeSubdirectories = $true
$watcher.EnableRaisingEvents = $true
### DEFINE ACTIONS AFTER AN EVENT IS DETECTED
$action = {
start-process C:\inetpub\wwwroot\exports\services\execute.bat
}
### 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 1}
The above script monitors C:\inetpub\wwwroot\exports\ folder and if there is any change to this folder, the $action is called. This script is not working and I see "Not started" error as below:
Any help on how to fix this?
I think its a "feature", the $action script should fire. It only seems to enter Running state after the first event has been fired.
Temporarily insert below before while ($true) {sleep 1} and you should see the state change:
Get-Job
Set-Content -Path "$($watcher.Path)\a_test_file.txt" -Value "hello"
Get-Job
(And for the sake of completeness Get-Job -Id 1 | Stop-Job -PassThru | remove-Job to stop and remove job id #1 - change id as required)

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
}

External powershell scripts only run once when action called

I am trying to call an outside ps script to run every time files are created. The monitoring and logging of files work well, but the Invoke-Expression of running the external script only runs one time even if more files are created. How do I run the external script with every time a new file is created.
### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "c:\mypath"
$watcher.Filter = "*.txt*"
$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 "C:\mypath\log.txt" -value $logline
Invoke-Expression (start powershell ("C:\MyOtherScript.ps1")) ###### This only runs one time even if file is changes and logged
}
### DECIDE WHICH EVENTS SHOULD BE WATCHED
Register-ObjectEvent $watcher "Created" -Action $action
while ($true) {sleep 5}
EDIT: This got it working incase anyone find themselves here looking to solve the porblem
### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "c:\mypath"
$watcher.Filter = "*.txt*"
$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 "C:\mypath\log.txt" -value $logline
Start-Process powershell -argument "C:\MyOtherScript.ps1"
}
### DECIDE WHICH EVENTS SHOULD BE WATCHED
Register-ObjectEvent $watcher "Created" -Action $action
#while ($true) {sleep 5}
Invoke-Expression is not recommend over using & due to security concerns. In your example, however, I'd suggest Start-Process:
Start-Process -FilePath 'powershell' -ArgumentList #('-File','"C:\MyOtherScript.ps1"')

how to monitor a folder in windows a run a batch file

I was following this SO answer to monitor a folder , but it is working one time. I mean if create a folder or file the batchfile will run , I created again a folder or edite it , it wont trigger
### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "C:\Users\uuu\Desktop\new folder\tttt"
$watcher.Filter = "*.*"
$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:\Copyof\PSlog.txt" -value $logline
cmd.exe /k "D:\Copyof\move.bat"
}
### 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 1}
Just so this gets an official answer:
Isn't the problem coming from your "/k" flag on cmd.exe? It means execute the command and remain. – David Brabant
/K Run Command and then return to the CMD prompt. This is useful for testing, to examine variables – Matt
Use a /C instead. – SomethingDark