SikRikDaRula
SikRikDaRula

Reputation: 133

Monitor Network folder for files

I am trying to run this query in powershell, but when I run it with the current $MonitorFolder as \\\vavm\CINICO\Incoming my query does not work when adding a file to the folder. If I change the variable of $MonitorFolder to C:\Users\RickG\Desktop\Test Reports, my code works fine when adding the file to the folder. So how do I monitor the \\vavm\CINICO\Incoming path for when files are added to folder.

Here is a snippet of my first part of code that checks the folder:

$MonitorFolder = "\\vavm\CINICO\Incoming"
$MonitorStopFile = "monitor.die"
$smtpServer = "mail.test.org"
$smtpFrom = "[email protected]" 
$smtpTo = "[email protected]"


$SourceID = "MonitorFiles"

$smtpSubject = "New file arrived in $($MonitorFolder)" 
$Query = @"
SELECT * FROM __InstanceCreationEvent WITHIN 10
WHERE targetInstance ISA 'Cim_DirectoryContainsFile'
AND targetInstance.GroupComponent = 'Win32_Directory.Name="$($MonitorFolder.Replace("\", "\\\\"))"'
"@

SOLUTION:

$MonitorFolder = "\\vavm\CINICO\incoming"
$MonitorStopFile = "monitor.die"

$smtpServer = "mail.test.org"
$smtpFrom = "[email protected]" 
$smtpTo = "[email protected]"
$smtpSubject = "New file arrived in $($MonitorFolder)" 
$SourceID = "MonitorFiles"
$IncomingFiles = Get-ChildItem $MonitorFolder

$smtp = New-Object -TypeName "Net.Mail.SmtpClient" -ArgumentList $smtpServer

$watcher = New-Object System.IO.FileSystemWatcher $MonitorFolder
#Files only. Default is files + directory
$watcher.NotifyFilter = [System.IO.NotifyFilters]'FileName,LastWrite'

$newFileSubscription = Register-ObjectEvent -InputObject $watcher -EventName Created -SourceIdentifier NewFileCreated -Action { 
Write-Host "New file named '$($Event.SourceEventArgs.Name)' arrived in $($MonitorFolder)"

$smtpBody += "`n[$(Get-Date -Format HH:mm:ss)]`tNew file named '$($Event.SourceEventArgs.Name)' arrived in $($MonitorFolder)"

if($Event.SourceEventArgs.Name -eq $MonitorStopFile) {
    Write-Host "Monitoring stopped"
    #Stop monitoring
    Unregister-Event -SubscriptionId $newFileSubscription.Id
    #Dispose FileSystemWatcher
    $watcher.Dispose()
}
$smtp.Send($smtpFrom, $smtpTo, $smtpSubject, $smtpBody)      
}

Upvotes: 0

Views: 2363

Answers (1)

Frode F.
Frode F.

Reputation: 54821

I'm 99% sure __InstanceCreationEvent doesn't support remote shares. WMI-events are trigged by your computer even if you don't have anything subscribing to it. Your computer can't monitor ever fileshare on the network.

You should try System.IO.FileSystemWatcher to monitor remote shares. Ex.

$MonitorFolder = "\\vavm\CINICO\Incoming"
$MonitorStopFile = "monitor.die"

$smtpServer = "mail.test.org"
$smtpFrom = "[email protected]" 
$smtpTo = "[email protected]"
$smtpSubject = "New file arrived in $($MonitorFolder)" 
$SourceID = "MonitorFiles"

$smtp = New-Object -TypeName "Net.Mail.SmtpClient" -ArgumentList $smtpServer

$watcher = New-Object System.IO.FileSystemWatcher $MonitorFolder
#Files only. Default is files + directory
$watcher.NotifyFilter = [System.IO.NotifyFilters]'FileName,LastWrite'

#Using a thread-safe collection (in global scope so Action-block can reach it) to store the log just to be safe.
$global:newFiles = [System.Collections.ArrayList]::Synchronized((New-Object System.Collections.ArrayList))

$newFileSubscription = Register-ObjectEvent -InputObject $watcher -EventName Created -SourceIdentifier NewFileCreated -Action {   
    Write-Host "New file named '$($Event.SourceEventArgs.Name)' arrived in $($MonitorFolder)"
    $global:newFiles.Add("[$(Get-Date -Format HH:mm:ss)]`tNew file named '$($Event.SourceEventArgs.Name)' arrived in $($MonitorFolder)")

    if($Event.SourceEventArgs.Name -eq $MonitorStopFile) {
        Write-Host "Monitoring stopped"
        #Stop monitoring
        Unregister-Event -SubscriptionId $newFileSubscription.Id
        #Dispose FileSystemWatcher
        $watcher.Dispose()
    }
}

while ($watcher.EnableRaisingEvents -or $global:newFiles.Count -gt 0) {   

    #Sleep
    Start-Sleep -Seconds 60

    if($global:newFiles.Count -gt 0) {
        #Convert list of strings to single string (multiline)
        $smtpbody = $global:newFiles | Out-String

        $smtp.Send($smtpFrom, $smtpTo, $smtpSubject, $smtpBody) 

        #Mail sent, Empty array
        $global:newFiles.Clear()
    }

}

Updated the sample above with a thread-safe global arraylist to store the "newfiles"-log in and a while-loop to create a mail ever minute if there are new items in the log.

Upvotes: 3

Related Questions