Email alerts for completion errors with scheduled FreeFileSync jobs

Update(2014/04/24): You can find more on this topic at the following forum post: http://www.dostips.com/forum/viewtopic.php?f=3&t=5518&sid=26b92a8482829a3d758d3edd9bc09b96 – also in Andrea’s comments below.

Update (2012/03/07): So I really thought I had this working, but found I’d left off something quite important! On the findstr line there was a missing switch before the search string. I’ve now added it below.

Update (2012/01/16): I’ve added a few lines so the log file is zipped before it’s sent and then deleted afterwards. I use 7zip but you could use something else. See code below.

I’m a big fan of FreeFileSync and use it at work for a few back up processes. However, it doesn’t have any error reporting/email alerting built into it. This means I have to manually check logs for errors. Adding complexity (i.e. additional required user steps) to back up processes is a terrible idea, so automating this processes would be a lot better.

One of the recent versions of the application included a new feature where it would execute a command line upon completion of a synchronization. With a bit of Googling I came up with a batch file to use with it. You’ll need to download mailsend from here:

http://www.muquit.com/muquit/software/mailsend/mailsend.html

Create a file called emailalert.bat. Edit it and add the code below. Be careful with line breaks. There should be 9 lines in total. The lines begin with (ish): @echo; timeout; for; findstr; if; 7zip; mailsend; del); respectively.  You’ll need to change the email settings, log location and mailsend location in order to get it working as expected.

@echo off
timeout 30
for /f "delims=" %%x in ('dir "C:\Log Location" /od /b') do set recent=%%x
findstr /m /C:"completed with errors!" "C:\Log Location\%recent%"
if %errorlevel%==0 (
"C:\Program Files\7-Zip\7z.exe" a "C:\Log Location\%recent%.7z" "C:\Log Location\%recent%"
"C:\Mailsend Location\mailsend.exe" +bc +cc -smtp smtpaddress -t to@address -f from@address -user username -pass password -sub "FreeFileSync Backup: %time%, %date% - Completed with errors!" -attach "C:\Log Location\%recent%"
del "C:\Log Location\%recent%.7z"
)

Once you’ve created this and edited it. I would change the errorlevel value to “1” and run it (this will send the error message even if your last sync completed successfully  – I’m assuming it did!) so you can test all the settings work correctly. Might take a few attempts to get mailsend up and running.

Once it’s working correctly and you’re receiving the emails with the log attachments, change the errorlevel back. Then add the full filepath to the batch file to FreeFileSync in Synchronization Settings under ‘On completion’.

The ‘timeout’ is in the script because I think there’s a bit of a delay before the log file is finished being created once the bat file is executed. I’m sure you could get away with a shorter delay, but I’d rather have a longer delay and definitely receive the error alert email. This command works under Windows 7/Server 2008 but for earlier versions of Windows you’ll need to use a different command line. Try some of the suggestions here:

http://www.robvanderwoude.com/wait.php

14 comments so far

  1. monasera on

    so can this be good for synctoy 2.1

    • James on

      Hello. It wouldn’t work with SyncToy, but you could use it as an alternative, I believe.

  2. Scott on

    There is a better way to do this.
    Just write a PowerShell script to monitor the FreeFileSync logs directory and then email newly created logs to yourself. Done.
    The script is not easy, but it’s do-able, and doesn’t require and finagling with the log file names and doesn’t require any 3rd party EXEs.
    If you don’t see a log coming to you daily (or whatever you set the freq to) then you know something is really really wrong.
    I’ll try to get back here and post a link to the script I wrote (which you run as a background task).

    • Scott on

      Actually there’s 2 choices.
      Choice 1 is what I said in the prior post, but having to run an extra background process could be considered too complex, so…
      Choice 2 is to wrap the FreeFileSync job in a powershell script that emails the log after the job is complete. Then just run (or schedule) the powershell script to do the job and email you the result.
      Here is the script:

      # This script wraps a FreeFileSync job so that it will email the resulting log somewhere.

      # Note that it is designed to work with a default 64 bit install with no customization.

      # ——- Fill out this info below (the example entries use a fictitious gmail address)

      $Email_Address = “me@gmail.com”
      $Email_Username = “me@gmail.com”
      $Email_Password = “whatever my email password is”
      $Email_Server = “smtp.gmail.com”
      $Email_Port = 587

      $JobName = “Mirror_RAID” ; # This is the name of your free file sync job file (without the extension).

      $JobsDir = “D:\Profiles” ; # This is the directory that holds the job file (the ffs_batch file) you want to run
      $LogsDir = “D:\Logs” ; # This directory has a subdirectory called “Archive” where all the logs end up, and also a subdirectory for each job to be used as a temp dir (both these directories must pre-exist or the script will fail)

      # ——– Don’t have to change anything below here

      $JobFile = (join-path $JobsDir $JobName) + “.ffs_batch”

      $LogDir = join-path $LogsDir $JobName
      $ArchiveDir = join-path $LogsDir “Archive”

      $existinglogfiles = join-path $LogDir “*”

      remove-item $existinglogfiles -recurse

      $FreeFileSync = join-path ${env:ProgramFiles} “FreeFileSync\bin\FreeFileSync_x64.exe”

      $proc = Start-Process -FilePath $FreeFileSync -ArgumentList $JobFile -passthru -wait

      $exitcode = $proc.ExitCode

      if ($exitcode -eq 0)
      {
      $result = “completed”
      }
      else
      {
      $result = “failed”
      }

      $fileEntries = [IO.Directory]::EnumerateFiles($LogDir)

      foreach ($fileEntry in $fileEntries)
      {
      $logfilepathname = $fileEntry
      $fileName = split-path $fileEntry -leaf
      $archivefilepathname = join-path $ArchiveDir $fileName
      }

      Move-Item $logfilepathname $archivefilepathname

      $password = ConvertTo-SecureString $Email_password -AsPlainText -Force

      $creds = new-object -typename System.Management.Automation.PSCredential -argumentlist $Email_Username, $password

      $param =
      @{
      SmtpServer = $Email_Server
      Port = $Email_Port
      UseSsl = $true
      Credential = $creds
      From = “File Sync Demon ” + $Email_Address
      To = $Email_Address
      Subject = ‘File Sync ‘ + $result
      Body = “See attachment for log.”
      Attachments = $archivefilepathname
      }

      try
      {
      Send-MailMessage @param -ErrorAction Stop
      $ok = $true
      }
      catch
      {
      $ok = $false
      }

      if (-not ($ok))
      {
      write-host “FAILED!”
      write-host “$_.Exception”
      sleep 60
      }

      • James on

        Thank you for sharing this, Scott!

  3. Andrea M. on

    Hello,
    I am trying to send logs for every errorcode I can get but I need some help with the configuration. I’ve copied a script here and I am updating it for my “global” configuration. If this works it will be perfect for all my needs.
    Please see below if you can help finishing the string.

    This is my modified working code:

    @echo off
    timeout 1
    for /f “delims=” %%x in (‘dir “C:\FFS\Logs\” /od /b’) do set recent=%%x
    findstr /m /C:”completed with errors” “C:\FFS\Logs\%recent%”
    if errorlevel 0 (
    “C:\FFS\mailsend.exe” +bc +cc -v -smtp smtp.gmail.com -ssl -port 465 -auth -from EMAIL -to EMAIL -cc 2NDEMAIL -user EMAIL -pass PASSWORD -sub “FFS Backup/NAMEBACKUP: %time%, %date% – [Failed] Synchronization completed with errors” -attach “C:\FFS\Logs\%recent%”
    )

    This is what I am trying to achieve:

    @echo off
    timeout 1
    for /f “delims=” %%x in (‘dir “C:\FFS\Logs\” /od /b’) do set recent=%%x
    findstr /m /C:”completed with errors” “C:\FFS\Logs\%recent%”
    if errorlevel 0 (
    “C:\FFS\mailsend.exe” +bc +cc -v -smtp smtp.gmail.com -ssl -port 465 -auth -from EMAIL -to EMAIL -cc 2NDEMAIL -user EMAIL -pass PASSWORD -sub “FFS Backup/BACKUPNAME: %time%, %date% – [Success] Synchronization completed successfully” -attach “C:\FFS\Logs\%recent%”
    )
    if errorlevel 1 (
    “C:\FFS\mailsend.exe” +bc +cc -v -smtp smtp.gmail.com -ssl -port 465 -auth -from EMAIL -to EMAIL -cc 2NDEMAIL -user EMAIL -pass PASSWORD -sub “FFS Backup/BACKUPNAME: %time%, %date% – [Failed/Warnings] Synchronization completed with warnings” -attach “C:\FFS\Logs\%recent%”
    )
    if errorlevel 2 (
    “C:\FFS\mailsend.exe” +bc +cc -v -smtp smtp.gmail.com -ssl -port 465 -auth -from EMAIL -to EMAIL -cc 2NDEMAIL -user EMAIL -pass PASSWORD -sub “FFS Backup/BACKUPNAME: %time%, %date% – [Failed/Errors] Synchronization completed with errors” -attach “C:\FFS\Logs\%recent%”
    )
    if errorlevel 3 (
    “C:\FFS\mailsend.exe” +bc +cc -v -smtp smtp.gmail.com -ssl -port 465 -auth -from EMAIL -to EMAIL -cc 2NDEMAIL -user EMAIL -pass PASSWORD -sub “FFS Backup/BACKUPNAME: %time%, %date% – [Failed/Aborted] Synchronization aborted” -attach “C:\FFS\Logs\%recent%”
    )

    I have to change the two lines after timeout 1 but I don’t really know what to enter precisely.

    Thanks guys.

  4. Andrea M. on

    I got here but sometimes even when the log is Completed successfully the log reported and send is Failed with the succeeded log attached. Weird.

    This is my new scripts:

    @echo off
    timeout 1
    for /f “delims=” %%x in (‘dir “C:\FFS\Logs\” /od /b’) do set recent=%%x
    findstr /m /C:”successfully” “C:\FFS\Logs\%recent%”
    findstr /m /C:”warnings” “C:\FFS\Logs\%recent%”
    findstr /m /C:”errors” “C:\FFS\Logs\%recent%”
    findstr /m /C:”aborted” “C:\FFS\Logs\%recent%”
    findstr /m /C:”Nothing to synchronize” “C:\FFS\Logs\%recent%”
    if %errorlevel%==0 (
    “C:\FFS\mailsend.exe” +bc +cc -v -smtp smtp.gmail.com -ssl -port 465 -auth -from 1STEMAIL -to 1STEMAIL -cc 2NDEMAIL -user 1STEMAIL -pass PASSWORD -sub “FFS_COMPANYNAME/PCNAME-BACKUPNAME: %time%, %date% – [Success] Synchronization completed successfully” -attach “C:\FFS\Logs\%recent%”
    )
    if errorlevel 1 (
    “C:\FFS\mailsend.exe” +bc +cc -v -smtp smtp.gmail.com -ssl -port 465 -auth -from 1STEMAIL -to 1STEMAIL -cc 2NDEMAIL -user 1STEMAIL -pass PASSWORD -sub “FFS_COMPANYNAME/PCNAME-BACKUPNAME: %time%, %date% – [Failed] Synchronization completed with errors” -attach “C:\FFS\Logs\%recent%”
    )

    Can we setup two variables that say when two strings appear set success and send the success log, when the other three appear set failed and send the failed lot?

    Thanks.

    • Andrea M. on

      This seems to be working perfectly:

      @echo off
      timeout 1
      for /f “delims=” %%x in (‘dir “C:\FFS\Logs\” /od /b’) do set recent=%%x
      if %errorlevel%==0 (
      “C:\FFS\mailsend.exe” +bc +cc -v -smtp smtp.gmail.com -ssl -port 465 -auth -from 1STEMAIL -to 1STEMAIL -cc 2NDEMAIL -user 1STEMAIL -pass PASSWORD -sub “FFS_COMPANYNAME/PCNAME-BACKUPNAME: %time%, %date% – [Success] Synchronization completed successfully” -attach “C:\FFS\Logs\%recent%”
      )
      if errorlevel 1 (
      “C:\FFS\mailsend.exe” +bc +cc -v -smtp smtp.gmail.com -ssl -port 465 -auth -from 1STEMAIL -to 1STEMAIL -cc 2NDEMAIL -user 1STEMAIL -pass PASSWORD -sub “FFS_COMPANYNAME/PCNAME-BACKUPNAME: %time%, %date% – [Failed] Synchronization completed with errors” -attach “C:\FFS\Logs\%recent%”
      )

      • Andrea M. on

        It doesn’t. All logs are [Success].

      • James McCarthy on

        Hi Andrea. I’m afraid it has been far too long since I did this for me to offer any insight. I do not currently use this tool any more either, as I do not work in the same sort of role. Good luck with trying to solve your issue and if you do please feel to share it back here.

      • Andrea M. on

        James, thank you for your reply. Just wanted to share it because this is one of the first Google result when you search FFS email log.

        Finally, this is a perfectly working script, it took few days but I have it:

        @echo off
        set subject=[Result undetermined] The search terms were not found
        for /f “delims=” %%x in (‘dir “C:\FFS\Logs\” /od /b’) do set recent=%%x
        findstr /i /c:”successfully” /c:”Nothing to synchronize” “C:\FFS\Logs\%recent%” >nul && set subject=[Success] Synchronization completed successfully
        findstr /i “warnings errors aborted” “C:\FFS\Logs\%recent%” >nul && set subject=[Failed] Synchronization completed with errors

        “C:\FFS\mailsend.exe” +bc +cc -v -smtp smtp.gmail.com -ssl -port 465 -auth -from 1STEMAIL -to 1STEMAIL -cc 2NDEMAIL -user 1STEMAIL -pass PASSWORD -sub “FFS_COMPANYNAME/PCNAME-BACKUPNAME: %time%, %date% – %subject%” -attach “C:\FFS\Logs\%recent%”

        There is also a .vbs script here: http://sourceforge.net/p/freefilesync/discussion/open-discussion/thread/4dee285b/ that you can personalize and use. I like my script better because of the ability to attach logs and full customization with less code learning.

        Have a great day.

      • Andrea M. on

        If you can please add to the last reply, the code was tweaked and personalized here: http://www.dostips.com/forum/viewtopic.php?f=3&t=5518&start=30

        Thanks.

    • Unknow on

      I try use this scripts is not working.

  5. Andrea M. on

    You can delete the other posts, final working version:

    @echo off
    set subject=[Failed] The search terms were not found
    for /f “delims=” %%x in (‘dir “C:\FFS\Logs\” /od /b’) do set recent=%%x
    findstr /i /c:”successfully” /c:”Nothing to synchronize” “C:\FFS\Logs\%recent%” >nul && set subject=[Success] Synchronization completed successfully
    findstr /i “warnings errors aborted” “C:\FFS\Logs\%recent%” >nul && set subject=[Failed] Synchronization completed with errors
    “C:\FFS\mailsend.exe” +bc +cc -v -smtp smtp.gmail.com -ssl -port 465 -auth -from 1STEMAIL -to 1STEMAIL -cc 2NDEMAIL -user 1STEMAIL -pass PASSWORD -sub “FFS_COMPANYNAME/PCNAME-BACKUPNAME: %time%, %date% – %subject%” -attach “C:\FFS\Logs\%recent%”


Leave a comment