Strip attachments from Outlook 2011 using AppleScript

2012/03/09

Here is a script that will delete all the attachments from messages highlighted in Outlook 2011. To use it you can perform some sort of search in Outlook (like all messages over 10MB) and then select all the returned messages and run the script.

One issue is that Outlook will try and refresh the search results when it perceives something has changed in the database. This caused script errors when messages it was about to interact with disappeared half way through deleting the attachments of those messages (since the total message size dropped below the search filter). So the script silently ignores these errors and goes on to the next message. This can mean you have messages left after the script run that are still too large, so just run the script a few times until there are no messages left highlighted.

tell application "Microsoft Outlook"
  set msgs to current messages
  set sz to 0
  repeat with msg in msgs
    log "Subject: " & subject of msg
    set atts to attachments of msg
    repeat with att in atts
      set a to att
      try
        set asz to file size of a
        delete a
        set sz to sz + asz
      on error
        exit repeat
      end try
    end repeat
  end repeat
  log "Deleted " & ((sz / 1024) as integer) & "KB of attachments"
end tell

Comments

  • Great script! Do you know if “delete” can be changed to “save” so the script can be run twice to first Save all attachments before deleting?

  • Yup, you can change the save line to this:
    save a in “/Users/chrisl/Desktop/” & name of a
    to make it save all the attachments on the Desktop.

    You can also change the whole first repeat section to create a folder for each email, in case there are attachments with the same names:

    repeat with msg in msgs
    log “Subject: ” & subject of msg
    tell application “Finder”
    set p to path to desktop
    make new folder at p with properties {name:id of msg}
    end tell
    set atts to attachments of msg
    repeat with att in atts
    set a to att
    try
    set asz to file size of a
    save a in “/Users/chrisl/Desktop/” & id of msg & “/” & name of a
    set sz to sz + asz
    on error
    exit repeat
    end try
    end repeat
    end repeat

  • I was very happy to see this script. I was able to delete attachments from multiple messages in Entourage 2008, but that functionality disappeared in Outlook 2011 (and it’s not an option in Outlook 2010, either, as far as I can tell). I tested the script on 5 messages, 2 with 2 attachments and 3 with 1 attachment. The script removed 1 attachment from each of the 5 messages, leaving 2 of the messages with 1 attachment. Running the script a second time took care of the last 2 messages. Is that by design? Is it possible for the script to remove multiple attachments from a single message? My outcome wasn’t the result of the search filter, as mentioned above. I arranged the messages by “Attachment”, and two messages remained in that group after the script was run the first time.

    Thanks for making the script public!

  • It should delete all the attachments for each message, unless it encounters some sort of error whilst trying to delete the attachment. So it might be misinterpreting something as a failure condition.

    If you remove the four lines that are “try”, “on error”, “exit repeat” and “end try” then the script won’t check for an error condition after each attachment delete. If there really is an error after removing the first attachment then you should see what the error was.

  • I removed those four lines from the AppleScript file. On a message with 4 attachments, the new script removed 2, then brought up an Outlook dialog:

    The script encountered error “Microsoft Outlook got an error: Can’t get attachment 3 of outgoing message id 87805. Invalid index.” during execution

    This behavior is pretty reproducible for me. If I have 2 or more attachments with a message the script can never remove all of them without running into an error. I can definitely say it’s easy to live with having to apply the script more than once to multi-attachment messages.

  • Thanks.. I figured it out alardey actually.. I was trying to get it make a folder named the Subject field of the incoming email, if it didn’t alardey exist and then save the files in there, give links in the reply email and what not I now have another questions/problem..Do this not save .pdf attachments or am I doing something wrong? I have tried changing several lines and what not and can not get it to save .pdf’s or .jpeg’s.. those are the two that I’ve noticed so far.. I’m going to try a couple more formats and see too..

  • Is it possible to run a search in Outlook using Applescript?

    I would like to write a script to find all message to/from an email address, using the sender address of the current message. So I am looking at a particular message, run the script and Outlook conducts a search showing me a history of all the emails between me and that person.

    It seems to me that Microsoft hasn’t provided the functionality to run a search. I realise I could cycle through all messages (as you did in this script) and maybe assign a temporary category to matching messages. Then I could manually filter on that category, but that isn’t quite what I am after and certainly not very elegant.

    Do you have any ideas?

  • I don’t think there’s an Applescript method for doing this, I’d cycle through all the messages like you suggested. If you wanted to do this on the command line you could navigate to “/Users//Documents/Microsoft User Data/Office 2011 Identities//Data Records/Message Sources” and grep through the contents to find what you wanted.

  • Thanks for your reply.

    I nearly solved the problem using system event. Outlook provides a keystroke shortcut to start an advanced search, and I can then paste my prepared raw query string into the relevant box. That gets me 90% done. It is only a couple of clicks to finish this off – but I just can’t get them to work and unfortunately Outlook doesn’t provide keyboard control only mouse. I’ve read that it is trial and error to get a system event approach to work and can vouch for that (and I realise that it is a very clunky solution anyway)! Oh well.

  • I am using the script (original one) and what I get is the size becomes BIGGER than the original email.

    What am I missing ?

  • That’s weird, at the end of the run did the script tell you how much data it had deleted?

  • GREAT! Many thanx 4 this solution!

    (…but it’s a shame that Microsoft didn’t provide a “delete all attachments” solution…)

  • There’s an oddity in the script, probably due to Outlook. It _appears_ Outlook give the attachments new index numbers as you delete them, so you have four attachments:
    – a: index 1
    – b: index 2
    – c: index 3
    – d: index 4

    If you delete index 1, Outlook rejiggers and:
    – b: index 1
    – c: index 2
    – d: index 3

    The script then deletes index 2, and:
    – b: index 1
    – d: index 2

    The script then attempts to delete index 3 and fails.

  • Try:

    —–
    tell application “Microsoft Outlook”
    set msgs to current messages
    set sz to 0
    repeat with msg in msgs
    log “Subject: ” & subject of msg
    set atts to attachments of msg
    repeat with i from (count atts) to 1 by -1
    set a to item i of atts
    try
    set asz to file size of a
    delete a
    set sz to sz + asz
    on error
    exit repeat
    end try
    end repeat
    end repeat
    log “Deleted ” & ((sz / 1024) as integer) & “KB of attachments”
    end tell
    —–

  • Nice work!
    Your code has been added to another script.

  • Seriously… you are a damned hero!!

  • Hi, this is a great script, thank you!

    Could someone post the code to download selected attachments only, with the email Subject as the folder name rather than the id?

    many thanks & regards

    KK

  • No worries, work it out.

    tell application “Microsoft Outlook”
    set msgs to current messages
    set sz to 0
    repeat with msg in msgs
    set theName to subject of msg
    set fixName to theName as string
    set AppleScript’s text item delimiters to “/”
    set theString to text items of fixName
    set AppleScript’s text item delimiters to ” ”
    set fixName to theString as string
    set AppleScript’s text item delimiters to “”

    log “Subject: ” & subject of msg
    tell application “Finder”
    set p to “/Users/chrisl/Desktop/”
    make new folder at p with properties {name:fixName}
    end tell
    set atts to attachments of msg
    repeat with att in atts
    set a to att
    try
    set asz to file size of a
    save a in “/Users/chrisl/Desktop/” & fixName & “/” & name of a
    set sz to sz + asz
    on error
    exit repeat
    end try
    end repeat
    end repeat
    end tell

  • I saw your script and it is really great, but I’d do something else.
    I would like the script to save my attachments in a folder (example a folder named attachment) and in the email, he writes an html link to the place where the attachment is stored. So you can click on it and find it easily. Is this possible?

    thank you for your help

  • I have grabbed a few examples from other sources and written a script that will save each attachment in a subfolder based on the date the email was received. Hope this can save somebody else some time.

    — AppleScript to remove attachment from selected messages in Outlook 2011
    — Incorporates code from these sources:
    http://dice.neko-san.net/2012/03/strip-attachments-from-outlook-2011-using-applescript/
    http://stackoverflow.com/questions/9617029/how-to-get-the-a-file-url-in-osx-with-applescript-or-a-shell-script (for path2url function)
    https://gist.github.com/cweirup/3058303
    — 7/31/13 updated the script so that running the script on multiple emails does not cause the attachment list to grow. Moved “repeat with theMessage in selectedMessages” to a better place

    on path2url(thepath)
    — Needed to properly URL encode the path
    return do shell script “python -c \”import urllib, sys; print (urllib.quote(sys.argv[1]))\” ” & quoted form of thepath
    end path2url

    property disallowedChars : “:;,/|!@#$%^&*()+-”
    property disallowedChars2 : “‘”
    property replacementCharacter : “”

    on CleanName(theName)

    set newName to “”
    repeat with i from 1 to length of theName

    –check if the character is in disallowedChars
    –replace it with the replacementCharacter if it is
    if ((character i of theName) is in disallowedChars) then
    set newName to newName & replacementCharacter

    –check if the character is in disallowedChars2
    –remove it completely if it is
    else if ((character i of theName) is in disallowedChars2) then
    set newName to newName & “”

    –if the character is not in either disallowedChars or
    –disallowedChars2, keep it in the file name
    else
    set newName to newName & character i of theName

    end if
    end repeat

    return newName
    end CleanName

    tell application “Microsoft Outlook”
    — Get currently selected message
    — FOR NOW YOU CAN SELECT MULTIPLE EMAILS

    tell application “Finder”
    try
    tell me to set folder_path to (choose folder with prompt “Select a folder to save the attachments”) as text
    on error number -128
    — User canceled the action
    display dialog “No folder selected. Please rerun the script and select a folder.” with icon 2
    return number
    — Exit the script
    end try
    end tell

    set selectedMessages to current messages
    set attachmentSizes to 0

    repeat with theMessage in selectedMessages
    — this line was moved here to allow for multiple messages to be processed

    set fileDownloadedList to “Attachments Removed:————————”

    if selectedMessages is {} then
    display dialog “Please select a message first then run the script” with icon 1
    return
    end if

    — Check for attachments

    — Get the attachments

    set attachmentlist to every attachment in theMessage
    repeat with anAttachment in attachmentlist
    set a to anAttachment
    set theDate to time received of theMessage
    set theDate to short date string of theDate
    set fixDate to theDate as string
    set newDate to my CleanName(fixDate)

    try
    set attachmentSize to file size of a
    set fileDownloaded to folder_path & newDate & “:” & name of a

    — set receivedTime to time received of theMessage
    if not (exists folder newDate of folder folder_path) then
    tell application “Finder” to make new folder at folder_path with properties {name:newDate}
    end if

    — Save the attachment
    save a in folder_path & newDate & “/” & name of a

    — Log the file sizes and file list

    set attachmentSizes to attachmentSizes + attachmentSize

    set fileDownloadedURL to “file://localhost” & my path2url(POSIX path of fileDownloaded)
    set fileDownloadedList to fileDownloadedList & “Attachment: ” & fileDownloaded & “

    on error
    exit repeat
    end try

    end repeat

    set content of theMessage to fileDownloadedList & “” & content of theMessage

    — Need to delete the attachments here, otherwise we throw index errors
    — Becase Outlook resets the list when deleting, need to just keep deleting the first
    — item each time until all are removed
    set attachmentCount to count of attachmentlist
    repeat (attachmentCount) times
    delete item 1 of attachmentlist

    end repeat

    end repeat

    end tell

  • Will this work with IMAP folders and will the attachment be removed from the server as well?

  • Leave a comment