Monitor files with FileSystemWatcher - powershell

I'm trying to create a PowerShell program to monitor when a file in a certain path is modified, and only if it now contains the string "loaded successfully", to Write-Host. Eventually an email component will be added if the string is not found in a certain amount of time.
$folder = 'C:\Users\afila\Desktop\TEST' # Enter the root path you want to monitor.
$files = Get-ChildItem $folder
$filter = '*.txt' # 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 = $false;
NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'
}
# Function to search folder contents for a string
function Search-Folder {
$SearchTerm = "Loaded successfully"
foreach ( $file in $files) {
$text = Get-Content "$folder\$file"
if ($text | where {$text -like "*$SearchTerm*" }) {
Write-Host "The file '$file succeeded" -fore white
Out-File -FilePath C:\Users\afila\Desktop\SucceededLog.txt -Append -InputObject "The file '$file' completed at $timeStamp"
}
}
}
# Here, all the Changed event is registerd.
Register-ObjectEvent $fsw Changed -SourceIdentifier FileChanged -Action {
$name = $Event.SourceEventArgs.Name
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
$searchTerm = "Loaded successfully"
foreach ($file in $files) {
$text = Get-Content "$folder\$file"
if ($text | where {$text -like "*$searchTerm*"}) {
Write-Host "The file '$name' was $changeType at $timeStamp" -fore magenta
Out-File -FilePath C:\Users\afila\Desktop\TestLogItems\TestLog.txt -Append -InputObject "The file '$name' was $changeType at $timeStamp"
}
}
}
# To stop the monitoring, run the following commands:
Unregister-Event FileChanged

The FileSystemWatcher already gives you the full path to the file via the property $Event.SourceEventArgs.Path, so you don't need to loop over a list of files.
Register-ObjectEvent $fsw Changed -SourceIdentifier FileChanged -Action {
$path = $Event.SourceEventArgs.Path
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
$searchTerm = 'Loaded successfully'
if ((Get-Content $path) -like "*$searchTerm*"}) {
Write-Host "The file '$name' was $changeType at $timeStamp"
}
}

Related

moving files in order dependant on file name with powershell

I use PS script with filesystemwatcher to monitor a folder. In this folder files need to be picked up in a specific order, not in the order they are created. So:
Files "blabla-Important1.xml", "blabla-Important2.xml" and "blabla-Important3.xml" are placed in the "pick-up folder". Filesystemwatcher wants to move the files according to the script. Now I need the files to be placed in the "destination folder" in the order I want, let's say:
"blabla-Important2.xml",
"blabla-Important4.xml",
"blabla-Important3.xml",
"blabla-Important1.xml".
Any suggestions? Thanks in advance!
Here's the (partial) script:
$folder = '.\tstA'
$filter = '*.xml'
$destination = '.\tstB'
$fsw = New-Object IO.FileSystemWatcher $folder, $filter -Property #{
IncludeSubdirectories = $false
NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'
}
$onCreated = Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action {
$path = $Event.SourceEventArgs.FullPath
$name = $Event.SourceEventArgs.Name
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
Write-Host "$timeStamp The file '$name' was $changeType and moved for SFTP to $destination"
"$timeStamp The file '$name' was $changeType and moved for SFTP to $destination" | Set-Content
'.\tst.log'
Move-Item $path -Destination $destination -Force -Verbose
}

Adding filenames to an array?

I'm trying to add filenames of certain txt files on a watched folder to an array for further analysis. The code is as following
$Array = New-Object System.Collections.ArrayList
$onCreated = Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action {
$path = $Event.SourceEventArgs.FullPath
$name = $Event.SourceEventArgs.Name
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
Write-Host "The file '$name' at '$path'was $changeType at $timeStamp" -fore white
$file=Get-Item $root\UNB\TMP\FACT_TEMPORAL.TXT | Rename-Item -NewName {("print-"+'{0:yyyy-MM-dd-hh_mm_ss}{1}' -f (Get-Date),".txt")} –PassThru
$archivo=$file.Name
Remove-Item $root\UNB\TMP\FACT_TEMPORAL.txt
comprobar_archivo($archivo)
}
The function to add it to the array is:
function comprobar_archivo($archivo) {
Write-Host "COMPROBANDO ARCHIVO $archivo" -fore white
$Array.Add($archivo)
write-host "CONTENIDO INICIAL ARRAY $Array"
foreach ($element in $Array) {
limpia($element)
leeyedita($element)
printpdf($element)
borrar($element)
borrar_array($element)
}
}
Seems that the write-host "CONTENIDO INICIAL ARRAY $Array" is not showing anything, further more the script gets frozen, it wont execute anymore. I don't know what I'm doing wrong, or how should I pass the filenames correctly in order to work.
How do I delete a specific name from the array? I was using:
$Array.Remove([String[]]$archivo)
But it wont work...

Folder Monitoring using Powershell Not writing to a folder

I have set up the power shell script which is not currently writing to my outlog.txt file, can anyone see anything obvious? I am monitoring the C drive as it states in the first line.
Code:
$folder = 'C:\Users\GeorgeH\Documents\Count' # Enter the root path you want to monitor.
$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 = $false;NotifyFilter =
[IO.NotifyFilters]'FileName, LastWrite'}
# Here, all three events are registerd. You need only subscribe to events
that you need:
Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action {
$name = $Event.SourceEventArgs.Name
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
Write-Host "The file '$name' was $changeType at $timeStamp" -fore green
Out-File -FilePath C:\Users\GeorgeH\outlog.txt -Append -InputObject "The
file '$name' was $changeType at $timeStamp"}
Register-ObjectEvent $fsw Changed -SourceIdentifier FileChanged -Action {
$name = $Event.SourceEventArgs.Name
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
Write-Host "The file '$name' was $changeType at $timeStamp" -fore white
Out-File -FilePath C:\Users\GeorgeH\Desktop\outlog.txt -Append -\
InputObject "The file '$name' was $changeType at $timeStamp"}

Copy-Item does not work with FileSystemWatcher

I'm trying to create a watch folder on a network share that simply copies files (300mb-20gb) in size to a destination folder. The FileSystemWatcher and subscription works great with small files (i.e. 1-3kb). However, larger files do not copy. I do see a copy is triggered in the verbose stream, but no file is copied to the destination folder.
$Folder = "\\10.11.233.91\vol_tx01\delivered_media"
$Filter = "*.mxf"
$destination = "C:\Users\Leeds TX 11\Desktop\support\Testy"
$Watcher = New-Object IO.FileSystemWatcher $Folder, $Filter -Property #{
NotifyFilter = [IO.NotifyFilters]'Filename, LastAccess'
}
$onCreated = Register-ObjectEvent $Watcher Created -SourceIdentifier `
FileCreated -Action {
$path = $event.SourceEventArgs.FullPath
$name = $event.SourceEventArgs.Name
$ChangeType = $event.SourceEventargs.ChangeType
$Timestamp = $event.TimeGenerated
Write-Host "The file '$name' was $ChangeType at $Timestamp"
Copy-Item $path -Destination $destination -Force -Recurse -Verbose
}
Combination of issue were at hand. Firstly thank you JohnLBevan for pointing out LastWrite should be the notifyfilter to use. Also found that in this case copy-item does not wait for the file transfer in the source directory to close. I fixed this by putting in a while loop waiting for the file to be locked:
##################### DANGER BOX ####################################
$Folder = "C:\Users\Leeds TX 12\Desktop\Source" #Source dir
$Filter = "*.mxf" # MXF Filter
$destination = "C:\Users\Leeds TX 12\Desktop\Destination" # Destination dir
################### Watch for file system events###########################
$Watcher = New-Object IO.FilesystemWatcher $Folder, $Filter -Property #{
NotifyFilter = [IO.NotifyFilters]'LastWrite, Filename'
}
################### Register filesystemwatcher & subscribe to notifyfilters #################
$onCreated = Register-ObjectEvent $Watcher Created -SourceIdentifier filecreated -Action {
$path = $event.SourceEventArgs.FullPath
$name = $Event.SourceEventArgs.Name
$ChangeType = $Event.SourceEventargs.ChangeType
$Timestamp = $event.TimeGenerated
write-host "The file '$name' was $ChangeType at $Timestamp" # Debug
################# Wait for file lock collapse #########################################
while($True)
{
Try {
[IO.File]::OpenWrite($path).Close()
Break
}
Catch { Start-Sleep -Seconds 1}
}
#################### Copy item #############################
Copy-item $path -Destination $Destination -force -Recurse -Verbose}

copy in powershell does not work as excpected

I have the following powershell script that not quite work as I thought it would. I want to copy the new created file in the source folder ($folder) to my destination folder ($DestFolder), but no file is copied. Anyone see what could be wrong?
$SourceFolder = 'd:\temp\' # Enter the root path you want to monitor.
$folder = 'd:\temp' # Enter the root path you want to monitor.
$Destfolder = 'd:\temp2\' # Enter the root path you want to monitor.
$global:MySourceFolder = 'd:\temp\' # Enter the root path you want to monitor.
$global:MyDestfolder = 'd:\temp2\' # Enter the root path you want to monitor.
$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 = $false;NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'}
Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action {
$name = $Event.SourceEventArgs.Name
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
#Write-Host "The file '$name' was $changeType at $timeStamp" -fore green
Write-Host "path : $MyDestfolder$name" -fore green
Copy-Item (Join-Path $MySourceFolder $name) ($Destfolder)
Out-File -FilePath d:\temp\filechange\outlog.txt -Append -InputObject "The file '$name' was $changeType at $timeStamp"}
I believe it is working as intended. If the copy actually is part of the action, try moving that line inside the action script block.
The variable $name is empty outside the action scriptblock since the ObjectEvent has its own scope. If you need to access this variable from outside the Action scriptblock you could declare the variable using $global:name.
The following really should work (replace with this but save a copy of your code so you've got a backup first)
$folder = 'd:\temp'
$Destfolder = 'd:\temp2'
$filter = '*.*'
$fsw = New-Object IO.FileSystemWatcher $folder, $filter -Property #{
IncludeSubdirectories = $false
NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'
}
Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action {
$name = $Event.SourceEventArgs.Name
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
Write-Host "The file '$name' was $changeType at $timeStamp" -fore green
Copy-Item -Path (Join-Path $folder $name) -Destination $Destfolder
Out-File -FilePath "d:\temp\filechange\outlog.txt" -Append -InputObject "The file '$name' was $changeType at $timeStamp"
}