none
Automatically saving emails as msg files? RRS feed

  • Question

  • I hope someone will be able to help. I am trying to automatically save emails as .msg files. These emails are requests that are sent by the public via an online portal. The emails will then have an index file created relating to it and then uploaded into an EDM system. I need to save the email in its original format. I have done something similar before but saving attachments rather than the actual email.

    I had a number of attempts and the script below is the closest I have got but this is searching through “my” default email address and I need it to read though a different one, possibly a number of different ones. Does anyone know if this can be modified to parameterise an email address to search though?

    $DestinationPath = "c:\Support\files\"
    $EmailAddress = "Application.Emails@donny.gov.uk"
    
    #Removes invalid Characters for file names from a string input and outputs the clean string
    Function Remove-InvalidFileNameChars 
    {
        param
        (
            [Parameter(Mandatory=$true, Position=0)]
            [String]$Name
        )
        return [RegEx]::Replace($Name, "[{0}]" -f ([RegEx]::Escape([String] [System.IO.Path]::GetInvalidFileNameChars())), '-')
    }
    
    #Add Interop Assembly
    Add-type -AssemblyName "Microsoft.Office.Interop.Outlook" | Out-Null
    
    #Type declaration for Outlook Enumerations
    $olFolders = "Microsoft.Office.Interop.Outlook.olDefaultFolders" -as [type]
    $olSaveType = "Microsoft.Office.Interop.Outlook.OlSaveAsType" -as [type]
    $olClass = "Microsoft.Office.Interop.Outlook.OlObjectClass" -as [type]
    
    #Add Outlook Com Object, MAPI namespace, and set folder to the Inbox
    $outlook = New-Object -ComObject Outlook.Application
    $namespace = $outlook.GetNameSpace("MAPI")
    
    #
    $folder = $namespace.getDefaultFolder($olFolders::olFolderDrafts)
    #$folder = $namespace.getDefaultFolder($olFolders::olFolderDrafts)
    
    #Iterate through each object in the chosen folder
    foreach ($email in $folder.Items) 
    {
    
        #Get email's subject and date
        [string]$subject = $email.Subject
        [string]$sentOn = $email.SentOn
    
        #Strip subject and date of illegal characters, add .msg extension, and combine
        $fileName = Remove-InvalidFileNameChars -Name ($sentOn + "-" + $subject + ".msg")
    
        #Combine destination path with stripped file name
        $dest = $DestinationPath + $fileName
    
         $email.SaveAs($dest, $olSaveType::olMSG)   
    }


    • Edited by Shepsy Friday, September 28, 2018 12:10 PM
    • Moved by Perry-Pan Monday, October 1, 2018 1:54 AM
    Friday, September 28, 2018 11:53 AM

All replies

  • Hi Shepsy,

    As here we mainly focus on issues regarding Outlook client, I'm not familiar with script . I'll help move this case to Office for Developer forum to get a better response.

    Thank you for your understanding and support.

    Regards,

    Perry


    Please remember to mark the replies as answers if they helped. If you have feedback for TechNet Subscriber Support, contact tnsf@microsoft.com.


    Click here to learn more. Visit the dedicated forum to share, explore and talk to experts about Microsoft Teams.

    Monday, October 1, 2018 1:53 AM
  • Thank you Perry
    Monday, October 1, 2018 3:19 PM
  • Although much time has passed since it was written you may want to consider the issues discussed in https://blogs.msdn.microsoft.com/stephen_griffin/2008/01/08/no-msg-for-you/
    Monday, October 1, 2018 3:31 PM
  • So what exactly are you having problem with? Finding the messages? Saving them? Or something else?

    Are you saying you need to open a mailbox owned by another user? Take a look at the Namespace.GetSharedDefaultFolder method.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Monday, October 1, 2018 6:46 PM
  • The problem I am having is that I need it to read through a different email address rather than the default.  The powershell is run from  "Task Scheduler" and run under a admin user.

    The script above works perfect if I wanted to manually run it as myself or through "Task Scheduler" and there were emails in the admin users email folder.

    I would then parameterise the required email address to search through.

    Wednesday, October 3, 2018 2:57 PM
  • By "different email address" you mean a "mailbox owned by another user", right?

    Call Namesoace.CreateRecipient and pass the returned Recipient object to Namespace.GetSharedDefaultFolder instead of GetDefaultFolder you are using now.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Wednesday, October 3, 2018 3:07 PM
  • Hello Dmitry

    I assume that you meant Namespace rather than Namesoace

    I have tried google to find how to use "Namespace.CreateRecipient" but I am unsure how I would feed in various "shared" email addresses as a parameter.  The email address to search through would/could change dependant on the type of run required.



    • Edited by Shepsy Thursday, October 4, 2018 11:32 AM
    Thursday, October 4, 2018 11:08 AM
  • I am not sure what the problem is. Do you mean you are not sure how to prompt the user for an email address? Or how to retrieve it from elsewhere?

    Do you see the mailbox you want to search through in Outlook?


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Thursday, October 4, 2018 1:58 PM
  • I know how to pass the parameters into a powershell.  I am having difficulty in changing the default email address.  at the moment it looks like this:-

    #Add Interop Assembly
    Add-type -AssemblyName "Microsoft.Office.Interop.Outlook" | Out-Null
    
    #Type declaration for Outlook Enumerations
    $olFolders = "Microsoft.Office.Interop.Outlook.olDefaultFolders" -as [type]
    $olSaveType = "Microsoft.Office.Interop.Outlook.OlSaveAsType" -as [type]
    $olClass = "Microsoft.Office.Interop.Outlook.OlObjectClass" -as [type]
    
    #Add Outlook Com Object, MAPI namespace, and set folder to the Inbox
    $outlook = New-Object -ComObject Outlook.Application
    $namespace = $outlook.GetNameSpace("MAPI")
    
    #
    
    $folder = $namespace.getDefaultFolder($olFolders::olFolderDrafts)
    
    #

    which looks at the default email address of whoever runs the powershell.  Could you show me how to change it to change this to look in "FSMFakeApplications@council.gov.PS"?


    thanks
    • Edited by Shepsy Thursday, October 4, 2018 2:28 PM
    Thursday, October 4, 2018 2:27 PM
  • You can't. Outlook only runs against an existing profile - you can pass that profile name when calling Namespace.Logon (which does nothing if Outlook is already running).

    If you want to connect to an arbitrary Exchange mailbox, you will need to use a different API, such as Exchange Web Services or Redemption and its RDOSession.LogonHostedExchangeMailbox method.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Thursday, October 4, 2018 3:39 PM