Home > Office 2007 > Outlook rule to save attachments to a web directory

Outlook rule to save attachments to a web directory

If you are like me, you get a lot of email messages with attachments in your Outlook email account.  Wouldn’t it be nice to automate the migration of these attachments to a folder of your choosing?  Well, you can, and we will show you how.

First off, it pays to research your particular topic. If you are looking for an excellent primer, you can find some good information in the following book:

At my job, we have web pages that are automatically generated and emailed to us.  We are tired of manually moving these files to the appropriate web directory (in this case, samba shares that are mapped with drive letters assigned to them).  So, the logical solution is to use Outlook Rules to push the attachments to the mapped drive.  However, Outlook rules have one limitation: you can move messages to specific folders, but moving attachments is another matter that is almost impossible to perform with the default Outlook Rules wizard.  So, we are going to use Outlook’s built in Visual Basic Editor to create some custom code to drive the attachment migration.  Here is how we did it:

  1. Open up Outlook.  I am using Outlook 2007, but this should also work in Outlook 2003.  Go to Tools>Macro>Visual Basic Editor.
  2. With your project folder highlighted (in the top left, in the PROJECT pane; I just used the default project, Project1), right click and choose Insert>Module, double-click Project1, and then double-click Microsoft Outlook Objects. Double-click ThisOutlookSession to open a code window. 
    outlook_rule_screenshot
    Copy and paste the following code into the code window of the editor:
    Sub SaveAttachmentsToDisk(Item As Outlook.MailItem)
    Dim olkFolder As Outlook.MAPIFolder, _
    olkAttachment As Outlook.Attachment, _
    objFSO As Object, _
    strRootFolderPath As String, _
    strFilename As String, _
    intCount As Integer
    'Change the following path to match your environment
    strRootFolderPath = "z:\www\departments\webreports\"
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    Set olkFolder = Application.ActiveExplorer.CurrentFolder
    If Item.Attachments.Count > 0 Then
    For Each olkAttachment In Item.Attachments
    If objFSO.GetExtensionName(LCase(olkAttachment.FileName)) = "htm" Then
    strFilename = olkAttachment.FileName
    intCount = 0
    Do While True
    If objFSO.FileExists(strRootFolderPath & strFilename) Then
    intCount = intCount + 1
    objFSO.deletefile (strRootFolderPath & strFilename)
    Else
    Exit Do
    End If
    Loop
    olkAttachment.SaveAsFile strRootFolderPath & strFilename
    End If
    Next
    End If
    Set objFSO = Nothing
    Set olkAttachment = Nothing
    Set olkFolder = Nothing
    End Sub
  3. You will need to ensure that you have the proper security level set in order to properly process the script. In Outlook, go to Tools>Macro> Security.  I chose No security check for macros.  This might be too loose of a restriction for your environment; if so, try the next highest setting.
  4. Create a new Outlook rule (Tools>Rules and Alerts) to reflect your changes.  My rule looks for new messages from a specific email address and has an attachment (the web file that I want to move), moves the message to a specific folder (so I can have a backup of the message/attachment), then runs the module/script above to move the web file to the appropriate samba share.  Here is what my Rule Description looks like:
    
    
    Apply this rule after the message arrives
    from joeuser@email.com
    and which has an attachment
    and on this machine only
    move it to the WEBBACKUP folder
    and run Project1.SaveAttachmentsToDisk
  5. Hit Apply and OK to save your rule. A couple of caveats: this is a client-side rule, so you must keep Outlook running in order for the rule to process. Also, the code will overwrite any file (in my case, in the target samba share) that has the same name as the attachment. If you only wish to make a copy, you can append a number to the attachment name. To do so, replace this line of code:
    objFSO.deletefile (strRootFolderPath & strFilename)

    with

    strFilename = "Copy (" & intCount & ") of " & olkAttachment.FileName 

    That’s it!

View additional details at this Microsoft Support article.

Office 2007

April 24th, 2009
  1. Eric
    May 20th, 2009 at 21:17 | #1

    Thanks for the helpful post.

    I cannot get it to work however. First of all, in your script, I believe you don’t mean to have “>” and “&amp:” but “>” and “&” respectively.

    I am at work, using Exchange cached mode, attempting to save file attachments (TIFF files) into “c:\faxes\”. I have macro security set to none. My rule looks *exactly* like yours.

    I did do the code line replacement, because I don’t want to delete older files of the same name.

    Any ideas of how I might troubleshoot this?

  2. Thantos
    May 22nd, 2009 at 13:48 | #2

    Correct on the script special character conversion (thanks for pointing this out); I updated the code example to reflect this.
    As for troubleshooting, did you change line 14 (htm) file extension to reflect your tiff files (change to tif)? I am also under the assumption that you commented out line 20 in order to avoid the file deletion.

    I would recommend adding a msgbox to the script to ensure that the script is even getting called and running. For example: MsgBox(“testing the script”). If the MsgBox displays when you run the rule, the code is getting called.

    You might also want to try a new rule and a test script…one that just moves files that are smaller than your tif files (txt, for example). If these work, then it could be a file size limitation on your large tiff files.

    Please feel free to share your code as well, and we can troubleshoot together.

  3. Norm
    October 5th, 2009 at 22:11 | #3

    I tried using your VB script to save attachements. I pasted it into VB editor from the [vb] to [/vb] but when I compile and run it highlights the first word in the script “sub” and gives a complile error “expected :expression”

  4. Thantos
    October 9th, 2009 at 14:34 | #4

    @Norm
    Hi, Norm.
    Make sure you do not include the [vb] and [/vb] in your module, and also make sure to update your strRootFolderPath to reflect your environment/network drive. Everything else should work as-is (note: you might have to change the ‘htm’ extension if you are wanting to copy another filetype).

  5. October 23rd, 2009 at 00:45 | #5

    such a useful post. thanks for saving me hours of stuffing around trying to work out how to do this.

    It worked the first time for me. Much appreciated.

    Ben

  6. Thantos
    October 23rd, 2009 at 13:18 | #6

    Glad it was useful, Ben!

  7. October 29th, 2009 at 17:29 | #7

    I used this code yesterday and it worked miracles. Unfortunately, after restarting Outlook this morning, it no longer saves the files. It does move them to the specified folder, it just doesn’t save the attachment. Anyone have any ideas? Thanks.

    Lacy

  8. Thantos
    November 2nd, 2009 at 01:08 | #8

    Lacy,
    I have experienced this problem before, and, although I have not completely figured it out, I did come up with a bit of a work-around. Usually, if this happens, I go into the Outlook rule properties, manually rerun the rule (highlight rule, choose CHANGE RULE>Edit Rule Settings, hit NEXT until you get to “Finish Rule Setup,” check RUN THIS RULE NOW ON MESSAGES ALREADY IN INBOX, and then “Finish”), and it usually starts working again (automated). I will keep digging for a better solution, though.

  9. Duane
    December 14th, 2009 at 16:07 | #9

    This is sooooo cool. This is going to save me a bunch of head aches. Thanks a bunch!!!

  10. Leftnut
    December 23rd, 2009 at 07:05 | #10

    Just assistance to others, if it does not work (but does compile etc) ensure you’ve not accidentally dropped the trailing ‘\’ from the path otherwise it gets confused.

  11. Jeff
    January 19th, 2010 at 18:48 | #11

    The script won’t be an option when building the rule unless you remove the [vb] and [\vb].

    Wonderful code…thanks a bunch!@Thantos

  12. Rich
    February 3rd, 2010 at 00:30 | #12

    When I run it, I get a message box from outlook that says “Rules in Error The script “” doesn’t exist or is invalid.”

    Any ideas what I’ve done wrong?

  13. Rich
    February 3rd, 2010 at 01:16 | #13

    Nevermind. It works great. Somehow I renamed the main “Module1″. Thanks for publishing this.

  14. GB
    February 19th, 2010 at 08:54 | #14

    Hi there,
    I saved the code in VB. I set my security setting to medium and create a digital signature for the code and marked it as trusted in Outlook.
    However, if I try to create the rule and bind the code, Outlook cannot see it in the macro dropdown list.
    outlook 2003, windows XP.
    What am I missing?

  15. Thantos
    March 29th, 2010 at 14:46 | #15

    Try changing the security for macros: TOOLS>MACRO>SECURITY>NO SECURITY CHECK FOR MACROS. Also, make sure that you remove the [vb] and [/vb] code snippets from the code.

  16. Jeff
    August 12th, 2010 at 16:10 | #16

    Just wanted to let you know how much we appreciate you posting this code. Like a lot of others, we needed to automate the uploading of a file sent by email. This is a real jewel.

    Thanks!

  17. abhay
    October 5th, 2010 at 17:06 | #17

    Hi,

    We use something called attachlink in our office .i.e. when we attach some file to send as an attachment in outlook it will create a link and send that link to receipient. I tried to use the above code when I try to download the attachment it downloads the link. Please help.

  18. Mister M
    December 17th, 2010 at 13:55 | #18

    abhay, can you post the code that you are using?

  19. Reta
    December 22nd, 2010 at 17:37 | #19

    This works perfectly! It would be even MORE perfect if it could be possible to have the attachment saved with another filename – something more meaningful than, say, 0979_001.pdf. Specifically, could the filename be compiled from the subject line and the date of the email?

  20. Reta
    December 27th, 2010 at 17:00 | #20

    I figured it out! I modified two lines for my purposes:

    If objFSO.GetExtensionName(LCase(olkAttachment.FileName)) = “pdf” Then

    ‘This line creates the filename from the email subject and adds the current date
    strFilename = Item.Subject & ” ” & Format(CDate(Now), “yyyy_MM_dd”) & “.pdf”

  21. ben
    January 13th, 2011 at 18:50 | #21

    I want to move emails with only PDF attachments to a folder. Does anyone know if it is possible to specify which type of attachments triggers a rule?

  22. Thantos
    February 10th, 2011 at 19:38 | #22

    ben,
    Try changing this line:

    If objFSO.GetExtensionName(LCase(olkAttachment.FileName)) = “htm” Then

    to:

    If objFSO.GetExtensionName(LCase(olkAttachment.FileName)) = “pdf” Then

    What did we change? The “htm” attachment specification to “pdf”

  23. Sue
    March 23rd, 2011 at 18:18 | #23

    I am using your code above to save PDF attachments to folder. My goal however is to extract PDF attachments from e-mail, convert them to multi-page TIFF image before saving to a folder. Would it be possible to combine this code with yours to attain my goal? http://www.ehow.com/how_7645423_convert-pdf-tiff-vbnet.html

  24. Thantos
    April 9th, 2011 at 22:07 | #24

    This definitely sounds doable. You should be able to embed the code that you supplied into my code. The hard part is parsing the PDF file and saving each page as part of the TIFF, though, and then saving everything in the designated directory. Here is my attached code; I merged the two code snippets together, but PLEASE NOTE that I have not tested it. I am sure that it will need some tweaking, but it will hopefully point you in the right direction. Once I get a bit more free time (my apologies, as I am swamped now), I will see if I can get this working 100%.

    Sub SaveAttachmentsToDisk(Item As Outlook.MailItem)
    Dim olkFolder As Outlook.MAPIFolder, _
    olkAttachment As Outlook.Attachment, _
    objFSO As Object, _
    strRootFolderPath As String, _
    strFilename As String, _
    intCount As Integer
    Dim noAppend As TiffEncoder = New TiffEncoder(TiffCompression.Default, True)
    Dim pdf As PdfDecoder = New PdfDecoder(XXX)
    Dim i As Integer=0
    ‘Change the following path to match your environment
    strRootFolderPath = “z:\www\departments\webreports\”
    Set objFSO = CreateObject(“Scripting.FileSystemObject”)
    Set olkFolder = Application.ActiveExplorer.CurrentFolder
    If Item.Attachments.Count > 0 Then
    For Each olkAttachment In Item.Attachments
    If objFSO.GetExtensionName(LCase(olkAttachment.FileName)) = “pdf” Then
    strFilename = olkAttachment.FileName

    ‘Begin conversion of PDF to TIFF
    Do While i< numPages
    Dim img As AtalaImage = pdfDecoder.Read(strFilename,i,Nothing)
    noAppend.Save(outStream, img, Nothing)
    img.Dispose(XXX)
    outStream.Seek(0, SeekOrigin.Begin)
    i += 1
    Loop
    intCount = 0
    Do While True
    If objFSO.FileExists(strRootFolderPath & strFilename) Then
    intCount = intCount + 1
    objFSO.deletefile (strRootFolderPath & strFilename)
    Else
    Exit Do
    End If
    Loop
    'Save TIFF
    img.SaveAsFile strRootFolderPath & strFilename
    olkAttachment.SaveAsFile strRootFolderPath & strFilename
    End If
    Next
    End If
    Set objFSO = Nothing
    Set olkAttachment = Nothing
    Set olkFolder = Nothing
    End Sub

  25. June 27th, 2011 at 04:01 | #25

    This code was exactly waht I was looking for. However I want to add one thing. How do I run a an mdb file after I have this code save a txt file?

    I am going to use this to save incoming text files, but I need to run an mdb file to add them to my database.

    Scott

  26. David
    January 22nd, 2012 at 21:40 | #26

    This isn’t working for me. The rule is moving the emails to a folder, but it isn’t saving the attachments. The first time I manually ran the rule it asked for permission to run the script due to security, and I allowed it. This is the line I have edited in the code. It’s a valid path. Nothing is being saved to disk.
    strRootFolderPath = “e:\backup\”

  27. DavidA
    February 2nd, 2012 at 19:32 | #27

    Thanks for sharing. I am using this to file my receipts: I want to take a picture from my phone and send it to myself. I had to edit the folder location where I wanted my attachments saved as well as the attachment extension. It is working great.

  28. Drew
    April 28th, 2012 at 03:20 | #28

    Thank you, this is perfect. I have Google Analytics set up to email PDFs of my visitor data on a weekly basis. With close to 10 websites that I monitor regularly, this enabled me to have the files automatically downloaded to a single directory.

    Works perfectly in MS Outlook 2010
    Just modified the path to where my files are to be stored and replaced “htm” to “pdf” where appropriate.

    Thank you for this!

  29. Sue
    May 15th, 2012 at 20:07 | #29

    @Thantos
    I would like to pull both “pdf” and “tif” attachment out to a folder – how would I modify the script to do this?

  30. Jennifer Bennett
    May 17th, 2012 at 18:52 | #30

    This was extremely helpful for what i needed. I have a few question on this as far as the functions I need to use this for:

    1. I am trying to put this file in a ftp network so what i would have to do is change this line strFolderPath to something else but I was unsure how to code it to a specific networking pathway through an EI directoty

    2. The file names and formats are specific in the manner they are sent.. i was curious if this would work for that:
    strFilename = Item.Subject & ” ” & Format(CDate(Now), “yyyy_MM_dd”) & “.pdf”

    as far as the format ..it would be “wildcard_wildcard_ATMC” “wildcard_wildcard_OHT”

    They are send by subject lines in the the first twofield attributes but are distinguished to wish EI path by the “_OHT” attribute

    Any help you could provide would be appreciative.

  31. apar
    May 18th, 2012 at 14:28 | #31

    Thanks for the code. The code works fine a few times. Some times the attachments are not saved.
    I debugged and figured out what the issue was. Most of the items the mail item does not have attachments. In my opinion, that is because, the code gets activated even before the mail attachment gets downloaded completely. Is there anyway, I can get the rule to act a few seconds after the mail arrives than right away?

    Thanks

  32. Thantos
    May 22nd, 2012 at 19:05 | #32

    @Sue

    Replace line 18 with the following, multiple-condition IF statement:

    If ((objFSO.GetExtensionName(LCase(olkAttachment.FileName)) = “pdf”) OR (objFSO.GetExtensionName(LCase(olkAttachment.FileName)) = “tif”))
    THEN

  33. Thantos
    May 22nd, 2012 at 19:09 | #33

    @apar

    You can try adding a vbscript-based delay to the top of the script.

    In this case:

    Sleep (1000)

    Should produce a delay of 1 second. I recommend googling “visual basic delay” to help in finding something a bit more specific to your needs.

  34. Brad Johnson
    June 18th, 2012 at 00:14 | #34

    Worked great and I am glad the questions were answered. I save to a 1TB harddrive all the images from my security cameras. Perfec and simple! Outlook 2010, Windows 7 with Exchange 2010

  35. MCPC
    July 2nd, 2012 at 07:39 | #35

    hi
    i tried this code to send a specific incoming mail to my local HD
    but nothing happens
    the rule is running ( i checked it with msgbox)
    but the mail is not being send to the directory
    there’s not any attchment in the mail
    im using outlook 2010 with exchange.
    thanks.

  36. Arvind
    October 11th, 2012 at 08:58 | #36

    Thank you very much Thantos as your script helped me a lot today.

  37. ConnyD
    October 16th, 2012 at 16:35 | #37

    Hi,
    Just tried it and it worked the first time – just what I was looking for. Thank you so very much for publishing it.

  38. November 18th, 2012 at 23:18 | #38

    I am working on a website for our volunteer fire department and I need to upload our fire page-outs to the website for later usage. I have them sent to my email now and I am trying to send them to an FTP site. They are MP3 format. I am hoping to keep 3 months at a time of call logs.
    This is the best option I have found so far, good work.
    MarkB

  39. Sue
    March 18th, 2013 at 15:53 | #39

    I would like to modify the file name to be time received and file name. Time reflected as hour minute seconds (in two digits) without spaces or symbols – how would you edit this line to reflect that?

    strFilename = Item.Subject & ” ” & olkAttachment.FileName

  40. Sue
    March 19th, 2013 at 20:56 | #40

    Figured out the solution.

    strFilename = Format(CDate(Now), “hhmmss”) & ” ” & olkAttachment.FileName

  41. April 1st, 2013 at 01:21 | #41

    Just another “thank you” for this great solution !! It really helped us !

  42. Sue
    April 17th, 2013 at 20:46 | #42

    Another tip – we found that sender filenames where too long and interfered with other applications in our environment. Therefore we are now truncating the file name with the line below.

    strFilename = Format(CDate(Now), “hhmmss”) & ” ” & Right(olkAttachment.FileName, 11)

  43. Dan
    May 3rd, 2013 at 18:36 | #43

    Hi Really need urgent help here, i have applied your scripts and the strRootFolderPath, but everytimr i ran the script its only move the mail but did not copy the attachment to the specified folder assigned…the “CSV” file is <100KB. Any idea what else can go wrong here? Thaks.

  44. Dan
    May 3rd, 2013 at 18:37 | #44

    The modified scr should be as below:
    Sub SaveAttachmentsToDisk(Item As Outlook.MailItem)
    Dim olkFolder As Outlook.MAPIFolder, _
    olkAttachment As Outlook.Attachment, _
    objFSO As Object, _
    strRootFolderPath As String, _
    strFilename As String, _
    intCount As Integer
    ‘Change the following path to match your environment
    strRootFolderPath = “c:\Personal\Shell\EliteBnR\NETBackup\Monthly Reporting\Alerts Monitoring\”
    Set objFSO = CreateObject(“Scripting.FileSystemObject”)
    Set olkFolder = Application.ActiveExplorer.CurrentFolder
    If Item.Attachments.Count > 0 Then
    For Each olkAttachment In Item.Attachments
    If objFSO.GetExtensionName(LCase(olkAttachment.FileName)) = “csv” Then
    strFilename = olkAttachment.FileName
    intCount = 0
    Do While True
    If objFSO.FileExists(strRootFolderPath & strFilename) Then
    intCount = intCount + 1
    objFSO.deletefile (strRootFolderPath & strFilename)
    Else
    Exit Do
    End If
    Loop
    olkAttachment.SaveAsFile strRootFolderPath & strFilename
    End If
    Next
    End If
    Set objFSO = Nothing
    Set olkAttachment = Nothing
    Set olkFolder = Nothing
    End Sub

  45. Dan
    May 3rd, 2013 at 18:41 | #45

    FYI, i’m using Outlook 2013

  46. Thantos
    May 3rd, 2013 at 19:03 | #46

    @Dan
    Dan, try the following code; note that I added “On Error Resume Next” immediately below the “Do While True” line (be sure to replace the Word-style quotations):

    The modified scr should be as below:
    Sub SaveAttachmentsToDisk(Item As Outlook.MailItem)
    Dim olkFolder As Outlook.MAPIFolder, _
    olkAttachment As Outlook.Attachment, _
    objFSO As Object, _
    strRootFolderPath As String, _
    strFilename As String, _
    intCount As Integer
    ‘Change the following path to match your environment
    strRootFolderPath = “c:\Personal\Shell\EliteBnR\NETBackup\Monthly Reporting\Alerts Monitoring\”
    Set objFSO = CreateObject(“Scripting.FileSystemObject”)
    Set olkFolder = Application.ActiveExplorer.CurrentFolder
    If Item.Attachments.Count > 0 Then
    For Each olkAttachment In Item.Attachments
    If objFSO.GetExtensionName(LCase(olkAttachment.FileName)) = “csv” Then
    strFilename = olkAttachment.FileName
    intCount = 0
    Do While True
    On Error Resume Next
    If objFSO.FileExists(strRootFolderPath & strFilename) Then
    intCount = intCount + 1
    objFSO.deletefile (strRootFolderPath & strFilename)
    Else
    Exit Do
    End If
    Loop
    olkAttachment.SaveAsFile strRootFolderPath & strFilename
    End If
    Next
    End If
    Set objFSO = Nothing
    Set olkAttachment = Nothing
    Set olkFolder = Nothing
    End Sub

  47. BillA
    May 10th, 2013 at 18:16 | #47

    Hello,
    I find the fact this code works with Outlook rules extremely creative and helpful.

    I am looking for suggestions to remove (delete) previously transferred files in a folder. Presently I receive 5-8 emailed .csv reports twice a week. The attached .csv file names are modified with the report run date at the end of the file name, e.g: Report_Name_05_10_2013. Each report file name varies in length, but the last 10 digits are ##_##_####.

    I would like to delete the file in my folder when the corresponding report is received. My goal is to only have the most recently received file in my folder. If it matters – I am presently using W2003 on xp, and soon to be upgraded to 2010 on W7.

    Any suggestions?

  48. christina
    June 5th, 2013 at 06:37 | #48

    HI,
    I need help.
    whenever the mail arrives with the subject “FTP download” in outlook, need to download a file from FTP server automatically.

    Any help for this?

  1. November 17th, 2010 at 20:26 | #1
  2. November 17th, 2010 at 20:26 | #2
  3. September 6th, 2013 at 07:18 | #3