Jump to content

Save and/or Delete all Outlook Attachments


Recommended Posts

This is posted in reply to a question found here:


There are many reasons for wanting to do this, for instance, moving your attachments out of your PST and zipping them to save space, or to reduce the amount of data you have up on the Exchange server.

This is not tested extensively, so make sure you back up your data before trying this. You will have to uncomment the actions you want to perform, and if you want to save, yo might want to set a different directory.

$oIEErrorHandler = ObjEvent("AutoIt.Error","ComErrFunc")
global $COMerrnotify = true
Func ComErrFunc()
    If IsObj($oIEErrorHandler) Then
        if $COMerrnotify then
            Status("--> ComErrFunc: COM Error Encountered in " & @ScriptName)
            Status("----> Scriptline = " & $oIEErrorHandler.scriptline)
            Status("----> Number Hex = " & Hex($oIEErrorHandler.number, 8))
            Status("----> Number = " & $oIEErrorHandler.number)
            Status("----> Win Description = " & StringStripWS($oIEErrorHandler.WinDescription, 2))
            Status("----> Description = " & StringStripWS($oIEErrorHandler.description, 2))
            Status("----> Source = " & $oIEErrorHandler.Source)
            Status("----> Help File = " & $oIEErrorHandler.HelpFile)
            Status("----> Help Context = " & $oIEErrorHandler.HelpContext)
            Status("----> Last Dll Error = " & $oIEErrorHandler.LastDllError)
        $HexNumber = Hex($oIEErrorHandler.number, 8)
    Return 0

$ol = objCreate("Outlook.Application")
$ns = $ol.session
$pst = $ns.PickFolder
if not isobj($pst) then exit


func cleanAttachments($folderObj)
    $Items = $folderObj.Items
    if $Items.count > 0 then 
        Status("Processing messages...")
        for $position = 1 to $Items.count
            $Item = $Items.Item($position)
            $itemAttachments = $Item.Attachments
            if $itemAttachments.count > 0 Then
                Status($folderObj.name &"\"& $Item.subject & ": " & $itemAttachments.count)
                for $a = $itemAttachments.count to 1 step -1 ; we must delete them in reverse order, obviously
                    $attachment = $itemAttachments.item($a)
                    ;uncomment next line to save each attachment
                    ;$attachment.SaveasFile(@ScriptDir & "\" & StringMid(TimerInit(),3,13) &"_"& $attachment.DisplayName)
                    ;uncomment next line to delete attachment
    $subfolders = $folderObj.Folders
    $subFolder = $subfolders.GetFirst
    while isobj($subFolder)
        $subFolder = $subfolders.GetNext

func Status($text)
    ConsoleWrite($text & @crlf)

[font="Fixedsys"][list][*]All of my AutoIt Example Scripts[*]http://saneasylum.com[/list][/font]

Link to comment
Share on other sites

  • 7 months later...

this is SWEET!!!

how would I just automatically select a folder (eg Inbox)

I'm using

$oOutlookExp = $oOutlookApp.ActiveExplorer
$pst = $oOutlookExp.CurrentFolder

But that means the inbox has to be selected. I don't know how to specify the inbox or another folder.

Edited by JohnBailey
A decision is a powerful thing
Link to comment
Share on other sites

Global Const $olFolderInBox = 6

;$pst = $ns.PickFolder

$pst = $ns.GetDefaultFolder($olFolderInBox)

GLORIOUS DAY!! That's how you use olFolder and such!!! I couldn't figure it out. I've tried so many different things, while reading through MSDN and using the example scripts.

So how did you figure out that it is 6 ?


A decision is a powerful thing
Link to comment
Share on other sites

I found a Delphi reference and translated it. I also posted that translation here:


DaleHohm pointed out to me in that post that there is a much easier way to enumerate the constants for COM objects, but this should get you started. Enjoy!

[font="Fixedsys"][list][*]All of my AutoIt Example Scripts[*]http://saneasylum.com[/list][/font]

Link to comment
Share on other sites

  • 13 years later...

I can't believe how much I enjoy this application and community. I've been trying to write my own routine to do exactly what this does and feel stupid for not looking here first. I usually do come here and almost always find what I need. Some minor changes to the code and the problem I was having is solved. Some of you are geniuses. I'm not a coder, I'm a systems admin, so down deep coding is just not something I do well. In most cases I can get what I need done with my dirty coding methods, but saving an attachment from an email wasn't one of them. This routine though posted almost 14 years ago works like a champ with few modifications I needed.

If anyone is listening, I do have two questions - first is that the $attachment.Delete() does not work well for me for some reason. What I mean by that is when I was first testing, it appeared to work a few times, but in most cases the attachment isn't deleted. This isn't a major issue as I delete the email after the routine has run, but it would be better if the routine deleted the attachment. I am running the routine on a PC that is logged in with my user account but locked. Outlook 2013 is running on that PC minimized.

Another option and the second question is that I noticed $item is used in the routine. Would I be able to add in $item.Delete() to delete the actual email itself?

I've added in an If/EndIf line so the only file the attachment is saved from meets the file name I'm looking for:

If $attachment.DisplayName = "filename.xxx" Then
     $attachment.SaveasFile("Y:\" & $attachment.DisplayName)

I have the $attachment.Delete() uncommented but as mentioned above, it doesn't usually delete the file from the email. So, can I add $item.Delete() and try to have the entire email deleted? (Never mind - I got bold and tried it - and it worked perfectly - The particular email was deleted! That resolves the problem of the attachment not always being deleted.)

Thank you again lod3n for posting this code. Even though posted 14 years ago, it's still very useful today. It just saved me manually having to save this file each morning for further processing by another system, that doesn't accept email or email attachments.

Thank you,


Edited by XF021209
Link to comment
Share on other sites

Did you have a look at my OutlookEX UDF? It provides almost everything you need when working with Outlook.

For download please see my signature :)

My UDFs and Tutorials:


Active Directory (NEW 2022-02-19 - Version - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version - Download
Outlook Tools (2019-07-22 - Version - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

ADO - Wiki
WebDriver - Wiki


Link to comment
Share on other sites

Thanks Water, I'll take a look. The modified Lod3n's code ran this morning almost perfectly. I didn't include the $item.Delete() until after it had run so that'll be a live test for tomorrow. The $item.Delete() actually works better for me, one less thing to delete out of the folder where the email with the attachment is delivered. In manual testing it worked so hopefully I'll see the same results in live testing. As mentioned I'm a system admin much more than a coder, and I really don't understand much of what you all write or how it all works, but I'm learning bit by bit. I am also amazed at how many different ways AutoIT can be used to accomplish the same task - so I will certainly look at your code, and learn as much as I can about it. I'm also looking to see how I can interface with an API for our companies Project Management (PPM) application. The current process I'm using Lod3n's code is for a report generated by the PPM, emailed to my Outlook, Lod3n's code strips off the report and places it in SharePoint. I use DataSyncStudio to read the previously attached file (it's user account information) and update a List in SharePoint. A SharePoint workflow then sends me an email for each account that does not reflect the data in our HR personnel system. All that is automated - now comes the manual part. I update the accounts in our PPM app manually. I'm looking into how I can make that part automated, so the PPM app reflects the data in our HR personnel system. It's so much fun having convoluted systems that don't like to talk to each other, a place I've found AutoIT fits in nicely, allowing me to automate otherwise manual only processes. The PPM app has limited API',s but hopefully I'll be able to get AutoIT to talk to the app and update the user account records. Thanks again,


Link to comment
Share on other sites

Beware you don't automate yourself out of a job if somebody stumbles onto your code!

I just -LOVE- backward compatibility where clean system/API calls are well documented and used in the manner in which the original developer intended, and when it is time to update they continue to work with the new software.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...