Monitor folder

Welcome Forums General PowerShell Q&A Monitor folder

Viewing 3 reply threads
  • Author
    Posts
    • #197069
      Participant
      Topics: 1
      Replies: 1
      Points: 15
      Rank: Member

      I have a script that monitors a folder and it's subfolders.  It is used by the ftp server as a landing location for when we receive ftp files.  The script sends an email to the recepients that a new file has been created in the folder.  The script works, but It sends an email for every file that was copied to the location.  I only want it to send 1 email to the recepients if a file was created in the last 6 hours.  This way if they ftp more than 1 file in the last 6 hours, then only 1 email goes out.  How can i modify my script to do this?

      # make sure you adjust this to point to the folder you want to monitor
      
      $PathToMonitor = “U:\FTPFolder\Test"
      
      explorer $PathToMonitor
      
      $FileSystemWatcher = New-Object System.IO.FileSystemWatcher
      
      $FileSystemWatcher.Path  = $PathToMonitor
      
      $FileSystemWatcher.IncludeSubdirectories = $true
      
      # make sure the watcher emits events
      
      $FileSystemWatcher.EnableRaisingEvents = $true
      
      # define the code that should execute when a file change is detected
      
      $Action = {
      
          $details = $event.SourceEventArgs
      
          $Name = $details.Name
      
          $FullPath = $details.FullPath
      
          $OldFullPath = $details.OldFullPath
      
          $OldName = $details.OldName
      
          $ChangeType = $details.ChangeType
      
          $Timestamp = $event.TimeGenerated
      
          $text = "{0} was {1} at {2}" -f $FullPath, $ChangeType, $Timestamp
      
          Write-Host ""
      
          Write-Host $text -ForegroundColor Green
      
          # you can also execute code based on change type here
      
          switch ($ChangeType)
      
          {
      
              'Changed' {
      
                          #$EmailFrom = “EmailAddress2@myemail.com”
      
                          #$EmailTo = “EmailAddress2@myemail.com, Person2@hotmail.com”
      
                          #$Subject = “New File FTP””
      
                          #$Body = $text
      
                          #$SMTPServer = “smtp.office365.com”
      
                          #$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
      
                          #$SMTPClient.EnableSsl = $true
      
                          #$SMTPClient.Credentials = New-Object System.Net.NetworkCredential(“EmailAddress1@myemail.com”, “Password”);
      
                          #$SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body)
      
                          #Start-Sleep -Seconds 4
      
                          #$SMTPClient.Dispose()
      
                          # this executes only when a file was renamed
      
                          $text = "File {0} was Changed" -f $FullPath
      
                          Write-Host $text -ForegroundColor Yellow
      
                        }
      
              'Created' {
      
                          $EmailFrom = “EmailAddress2@ myemail.com”
      
                          $EmailTo = “EmailAddress2@myemail.com, Person2@hotmail.com”
      
                          $Subject = “New File FTP”
      
                          $Body = $text
      
                          $SMTPServer = “smtp.office365.com”
      
                          $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
      
                          $SMTPClient.EnableSsl = $true
      
                          $SMTPClient.Credentials = New-Object System.Net.NetworkCredential(“EmailAddress1@myemail.com”, “Password”);
      
                          $SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body)
      
                          Start-Sleep -Seconds 4
      
                          $SMTPClient.Dispose()
      
                          # this executes only when a file was renamed
      
                          $text = "File {0} was Created" -f $FullPath
      
                          Write-Host $text -ForegroundColor Yellow
      
                        }
      
              'Deleted' {
      
                          #$EmailFrom = “EmailAddress2@ myemail.com”
      
                          #$EmailTo = “EmailAddress2@myemail.com, Person2@hotmail.com”
      
                          #$Subject = “New File FTP”
      
                          #$Body = $text
      
                          #$SMTPServer = “smtp.office365.com”
      
                          #$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
      
                          #$SMTPClient.EnableSsl = $true
      
                          #$SMTPClient.Credentials = New-Object System.Net.NetworkCredential(“EmailAddress1@myemail.com”, “Password”);
      
                          #$SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body)
      
                          #Start-Sleep -Seconds 4
      
                          #$SMTPClient.Dispose()
      
                          # this executes only when a file was renamed
      
                          $text = "File {0} was deleted" -f $FullPath
      
                          Write-Host $text -ForegroundColor Yellow
      
                          # uncomment the below to mimick a time intensive handler
      
                          <#
      
                          Write-Host "Deletion Handler Start" -ForegroundColor Gray
      
                          Start-Sleep -Seconds 4    
      
                          Write-Host "Deletion Handler End" -ForegroundColor Gray
      
                          #>
      
                        }
      
              'Renamed' {
      
                          #$EmailFrom = “EmailAddress2@ myemail.com”
      
                          #$EmailTo = “EmailAddress2@myemail.com, Person2@hotmail.com”
      
                          #$Subject = “New File FTP”
      
                          #$Body = $text
      
                          #$SMTPServer = “smtp.office365.com”
      
                          #$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
      
                          #$SMTPClient.EnableSsl = $true
      
                          #$SMTPClient.Credentials = New-Object System.Net.NetworkCredential(“EmailAddress1@myemail.com”, “Password”);
      
                          #$SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body)
      
                          #Start-Sleep -Seconds 4
      
                          #$SMTPClient.Dispose()
      
                          # this executes only when a file was renamed
      
                          $text = "File {0} was renamed to {1}" -f $OldName, $Name
      
                          Write-Host $text -ForegroundColor Yellow
      
                        }
      
              default { Write-Host $_ -ForegroundColor Red -BackgroundColor White }
      
          }
      
      }
      
      # add event handlers
      
      $handlers = . {
      
          Register-ObjectEvent -InputObject $FileSystemWatcher -EventName Changed -Action $Action -SourceIdentifier FSChange
      
          Register-ObjectEvent -InputObject $FileSystemWatcher -EventName Created -Action $Action -SourceIdentifier FSCreate
      
          Register-ObjectEvent -InputObject $FileSystemWatcher -EventName Deleted -Action $Action -SourceIdentifier FSDelete
      
          Register-ObjectEvent -InputObject $FileSystemWatcher -EventName Renamed -Action $Action -SourceIdentifier FSRename
      
      }
      
      Write-Host "Watching for changes to $PathToMonitor"
      
      try
      
      {
      
          do
      
          {
      
              Wait-Event -Timeout 1
      
              Write-Host "." -NoNewline
      
              
      
          } while ($true)
      
      }
      
      finally
      
      {
      
          # this gets executed when user presses CTRL+C
      
          # remove the event handlers
      
          Unregister-Event -SourceIdentifier FSChange
      
          Unregister-Event -SourceIdentifier FSCreate
      
          Unregister-Event -SourceIdentifier FSDelete
      
          Unregister-Event -SourceIdentifier FSRename
      
          # remove background jobs
      
          $handlers | Remove-Job
      
          # remove filesystemwatcher
      
          $FileSystemWatcher.EnableRaisingEvents = $false
      
          $FileSystemWatcher.Dispose()
      
          "Event Handler disabled."
      
      }
      
      • This topic was modified 2 weeks, 1 day ago by kvprasoon. Reason: code formatting
    • #197084
      Participant
      Topics: 2
      Replies: 1693
      Points: 3,368
      Helping Hand
      Rank: Community Hero
    • #197090
      Participant
      Topics: 10
      Replies: 1381
      Points: 1,509
      Helping Hand
      Rank: Community Hero

      The solution posted is made specifically for 'real-time', every 6 hours is actually more straight-forward. It looks like all of the emails are going to the same email thread? If you have different emails based on filenames or something to that effect, you can do something like this:

      $files = Get-ChildItem -Path 'C:\Scripts\*temp*.txt' -File | 
               Select FullName, 
                      LastWriteTime, 
                      @{Name='Email';Expression={'{0}@myemail.com' -f ($_.BaseName -split '_')[0]}}
      
      $grpFiles = $files | Group-Object -Property Email
      
      foreach ($grp in $grpFiles) {
          $params = @{
              To = $grp.Name
              Subject = 'You have {0} FTP files' -f $grp.Count
              Body = ($grp.Group | ConvertTo-Html -Property FullName, LastWriteTime | Out-String)
              BodyAsHtml = $true
          }
      
          $params
          #Send-MailMessage @params
      }
      

      The files look like this:

      PS C:\Users\rasim> $files
      
      FullName                    LastWriteTime         Email            
      --------                    -------------         -----            
      C:\Scripts\amy_Temp1.txt    11/22/2019 4:25:10 PM amy@myemail.com  
      C:\Scripts\amy_Temp2.txt    11/22/2019 4:25:10 PM amy@myemail.com  
      C:\Scripts\amy_Temp5.txt    11/22/2019 4:25:10 PM amy@myemail.com  
      C:\Scripts\amy_Temp8.txt    11/22/2019 4:25:10 PM amy@myemail.com  
      C:\Scripts\john_Temp0.txt   11/25/2019 9:28:47 AM john@myemail.com 
      C:\Scripts\john_Temp4.txt   11/22/2019 4:25:10 PM john@myemail.com 
      C:\Scripts\john_Temp6.txt   11/22/2019 4:25:10 PM john@myemail.com 
      C:\Scripts\john_Temp7.txt   11/22/2019 4:25:10 PM john@myemail.com 
      C:\Scripts\sally_Temp10.txt 11/22/2019 4:25:11 PM sally@myemail.com
      C:\Scripts\sue_Temp3.txt    11/22/2019 4:25:10 PM sue@myemail.com  
      C:\Scripts\sue_Temp9.txt    11/22/2019 4:25:10 PM sue@myemail.com
      

      The hours can be added or you can implement a process to move the files or flip an archive bit and then you are just getting all files that are not flipped which would work if the script errored out you could run it 15 hours later and it would just email all non-Archived files. The script could just be run as a scheduled task.

    • #197201
      Participant
      Topics: 1
      Replies: 1
      Points: 15
      Rank: Member

      Rob, thanks for the examples...this is very helpful and gives me a good starting point.  I will be sending an email to several people depending on the folder name, as each folder is for a different client.  If the client uploads 10 files in the last 6 hours, then i want to send out only 1 email confirming that the files were ftp to the folder.  I was using the filesystemwatcher to monitor any new files in the folders...but that was sending an email out for each file that was added to the folder.

Viewing 3 reply threads
  • You must be logged in to reply to this topic.