Monitor Folder and Email as Attachement

This topic contains 4 replies, has 4 voices, and was last updated by Profile photo of Rob Simmers Rob Simmers 1 year, 8 months ago.

  • Author
    Posts
  • #27212
    Profile photo of Graeme Simpson
    Graeme Simpson
    Participant

    Hi All,
    Just getting into Powershell by way of demands from the business.

    I am wanting to monitor a folder or set of folders, and if a file(s) appear, email them as an attachement to an address or maybe a couple of email addresses.

    I have tried various things, but nothing I do seems to do the job.

    Would anyone be kind enough to advise on a script to carry out this task.

    Thanks

  • #27213
    Profile photo of Don Jones
    Don Jones
    Keymaster

    This is not something PowerShell is awesomely suited for, but do some searched on "PowerShell FileSystemWatcher" and see if anything meets your needs. The FilesystemWatcher is a .NET Framework component that's much better at watching for changes, and it can then (sort of) call your PowerShell code to do whatever it is your'e after.

  • #27222
    Profile photo of Tim Curwick
    Tim Curwick
    Participant

    Graeme,

    It will depend on your exact requirements. I am going to assume that you don't need this to happen instantly, that new files can wait and be sent in aggregate every 5 minutes, or whatever. I am also going to assume for simplicity that the folders are a drop-off point, and the files are to be deleted (or moved to a backup folder) after they have been emailed. (It gets a bit more complex otherwise.)

    Use your favorite automation tool (or a simple scheduled task) to run something like this every 5 minutes, or every hour, or whatever. Be sure to run it as an account that has the required rights on the folders in question.

    $Folders = @( 'C:\Test1'
                  'C:\Test2' )
    $DestFolder = 'C:\TestProcessed'
    
    $EmailList = @( 'User1@contoso.com'
                    'User2@contoso.com' )
    
    $From       = 'admin@contoso.com'
    $Subject    = 'New files'
    $SMTPServer = 'smtp.contoso.com'
    
    #  Get new files
    $NewFiles = $Folders | Get-ChildItem -File -Recurse
    
    #  If there are an new files...
    If ( $NewFiles )
        {
        #  Add the file count and file names to the body of the email
        $Body = '$($NewFiles.Count) new files attached'
        $NewFiles | ForEach { $Body += $_.Name + "" }
    
        #  Send the email with attachments
        Send-MailMessage -From $From -To $EmailList -Subject $Subject -Body $Body -BodyAsHTML -Attachments $NewFiles.FullName -SmtpServer $SMTPServer
    
        #  Move the emailed files to the destination folder
        $NewFiles.FullName | Move-Item -Destination $DestFolder -Force
        }
    
  • #27242
    Profile photo of Graeme Simpson
    Graeme Simpson
    Participant

    Don many thanks for your information, I shall do a bit of searching and see how that pans out.

    Tim,

    Your assumptions were spot on, once the file has been sent it can be deleted, its of no use anymore, and I would just schedule to run every 15 mins or so.

    Really appreciate the time you have taken too post this information. I shall have a play around with it today and see how it goes, I will feedback later today when I have connectivity back as I am on the move.

    Once again many thanks

  • #27249
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    Just a couple of quick updates to Tim's script.

    1. Leverage splatting
    2. when passing multiple parameters

    3. The body of the email is HTML, so leverage ConvertTo-HTML when providing file information about the files attached
    4. This is more personal preference, but I don't like implicit foreach (e.g. $NewFile.FullName). I like to see the foreach construct and try to make script compatible with PS versions under V3.

    Here is a slightly tweaked version of Tim's script:

    $Folders = @( 'C:\Temp','C:\Test2' )
    $DestFolder = 'C:\TestProcessed'
    
    $emailSplat = @{
        To =  @( 'user1@contoso.com','user2@contoso.com' )
        From       = 'admin@contoso.com'
        Subject    = 'New files'
        SMTPServer = 'smtpserver'
        BodyAsHTML = $true
    }
    
    #  Get new files
    $NewFiles = Get-ChildItem -Path $Folders -File -Recurse -Include *.txt
    
    #  If there are an new files...
    If ( $NewFiles ) {
        #  Add the file count and file names to the body of the email
        $Body = $NewFiles | Select Name, FullName, LastWriteTime | ConvertTo-HTML -PreContent ("Attached Files ({0}):" -f $NewFiles.Count) -As Table
        $emailSplat.Add("Body", ($Body | Out-String))
    
        #Take attachements and add
        $Attachments = $NewFiles | Select -ExpandProperty FullName
        $emailSplat.Add("Attachments", $Attachments)
        
        #  Send the email with attachments
        Send-MailMessage @emailSplat
    
        #  Move the emailed files to the destination folder
        foreach ($file in $NewFiles) {Move-Item $file.FullName -Destination $DestFolder -Force}
    }
    

You must be logged in to reply to this topic.