I am writing a powershell script that will start a process, monitor a folder for file changes, and then backup that folder when files are added/changed.
If I run my script from within the Powershell ISE, it works fine, I can monitor the folder and it will properly save a backup as expected.
The problem is that I want to run a batch file that will run the powershell script. But whenever I run the script from a powershell console, or whenver I run my batch file which runs the script, it doesn't work any longer. The script runs and the events are registered. When I copy a file over to the watched folder though, I ONLY get the changed event and not the created event, and the doStuff function is no longer called. I'm not sure how to go about debugging this :/
Following is my script. I have removed parts that don't pertain to what is actualyl wrong currently, so some variables I'm using here you won't see declared but they are there. I get the write-host's to the console when the changed event happens but not the created event (though as stated eariler in the ISE, I get both events and everything works just fine)
#unregister events, in case they weren't unregistered properly before. Just error siliently if they don't exist
Unregister-Event ConsoleStopped -ErrorAction SilentlyContinue
Unregister-Event FileCreated -ErrorAction SilentlyContinue
Unregister-Event FileChanged -ErrorAction SilentlyContinue
Unregister-Event TimerTick -ErrorAction SilentlyContinue
#start the console process
Write-Host Starting console process...
$consoleProcess = Start-Process "$consoleExe" -PassThru
#register to listen for when the console stops
Register-ObjectEvent $consoleProcess Exited -SourceIdentifier ConsoleStopped -Action {
Write-Host Console stopped
#unregister events
Unregister-Event ConsoleStopped -ErrorAction SilentlyContinue
Unregister-Event FileCreated -ErrorAction SilentlyContinue
Unregister-Event FileChanged -ErrorAction SilentlyContinue
if(!$timer.Enabled) {
Unregister-Event TimerElapsed -ErrorAction SilentlyContinue
Remove-Item $timer
}
Remove-Item $fsw
Remove-Item $consoleProcess
}
#watch all files/folders
$filter = '*.*' # You can enter a wildcard filter here.
# In the following line, you can change 'IncludeSubdirectories to $true if required.
$fsw = New-Object IO.FileSystemWatcher $folder, $filter -Property @{IncludeSubdirectories = $true;NotifyFilter = [IO.NotifyFilters]'DirectoryName, FileName, LastWrite'}
#register for FileCreated event
Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action {
write-host Created event has occurred
doStuff($Event)
}
#register for FileChanged event
Register-ObjectEvent $fsw Changed -SourceIdentifier FileChanged -Action {
Write-Host Change event has occurred
doStuff($Event)
}
function doStuff($event)
{
write-host doStuff has been called
$name = $Event.SourceEventArgs.Name
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
Write-Host "The file '$name' in '$folder' was $changeType at $timeStamp" -fore green
if(!$timer.Enabled) {
Write-Host Starting save timer
Register-ObjectEvent $timer Elapsed -SourceIdentifier TimerElapsed -Action $TimerAction
$timer.Start()
Out-File "$backupDir\backup.log" -Append -Force -InputObject "A request for a backup created at $timeStamp"
}
else {
Write-Host A backup has already been request
}
}
function backupSave ()
{
Write-Host Starting backup...
$timestamp = Get-Date -Format o | foreach { $_ -replace ":", "." }
Copy-Item $folder "$backupDir\backup_$timestamp" -Recurse -Force
}