0
votes

I found the below script from here:

Can I save an email attachment from Office 365 to a file share with PowerShell?

$ewsPath = "C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll"
    Add-Type -Path $ewsPath
    
    $ews = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService
    $cred = (Get-Credential).GetNetworkCredential()
    $ews.Credentials = New-Object System.Net.NetworkCredential -ArgumentList $cred.UserName, $cred.Password, $cred.Domain
    $ews.AutodiscoverUrl( "[email protected]", {$true} )
    $results = $ews.FindItems(
        "Inbox",
        ( New-Object Microsoft.Exchange.WebServices.Data.ItemView -ArgumentList 100 )
    )
    $MailItems = $results.Items | where hasattachments
    
    foreach ($MailItem in $MailItems){
    
        $MailItem.Load()
    
        foreach($Attachment in $MailItem.Attachments){
            $Attachment.Load()
            $File = new-object System.IO.FileStream(("C:\AttachmentsDownloads\” + $attachment.Name.ToString()), [System.IO.FileMode]::Create)
            $File.Write($attachment.Content, 0, $attachment.Content.Length)
            $File.Close()
        }
    }

I can download the attachments, but when an email was attached as an attachment the download will fail. I have no idea what's the difference between a .msg file and a .pdf file when downloading it... and what I really need are the .msg attachments.

The error I am getting is below:

Exception calling "Write" with "3" argument(s): "Buffer cannot be null.
Parameter name: array"
At C:\DownloadAttachment.ps1:21 char:9
+         $File.Write($attachment.Content, 0, $attachment.Content.Lengt ...
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentNullException

Could you please help? Any help will be greatly appreciated!

2
What exactly happens when you say "the download will fail."? Any error messages? If so, please add these in full to your question.Theo
Thank you for your response. I edited the question and added the error message.AMA

2 Answers

0
votes

If you have an attached email then generally the Filename will be null so you need to generate a FileName for these type of attachments and load the Mime content so you can save it as a EML file see code below. The Msg file format (or compound OLE) is an Outlook file format so if you want that you will need to use and Outlook API (I would try Redemption)

$downloadDirectory = "C:\AttachmentsDownloads\"
$Attachment.Load()
if ($Attachment.ContentType -eq "message/rfc822") {
    $mimePropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.ItemSchema]::MimeContent)
    $Attachment.Load($mimePropertySet)
    $attachmentData = $attachment.Item.MimeContent.Content
    $fiFile = new-object System.IO.FileStream(($downloadDirectory + "\" + [GUID]::NewGuid().ToString() + ".eml"), [System.IO.FileMode]::Create)
    $fiFile.Write($attachmentData, 0, $attachmentData.Length)
    $fiFile.Close()
    write-host "Downloaded Attachment : " + (($downloadDirectory + "\" + $Attachment.Name.ToString()))
}else{
    $Attachment.Load()
    $File = new-object System.IO.FileStream(($downloadDirectory + "\" + $attachment.Name.ToString()), [System.IO.FileMode]::Create)
    $File.Write($attachment.Content, 0, $attachment.Content.Length)
    $File.Close()
}
0
votes

You can automate Outlook for getting MSG file attachments. Here is the code for getting unread items from the Inbox and saving attached files from them:

Outlook.MAPIFolder inBox = this.Application.ActiveExplorer()
        .Session.GetDefaultFolder(Outlook
        .OlDefaultFolders.olFolderInbox);
    Outlook.Items inBoxItems = inBox.Items;
    Outlook.MailItem newEmail = null;
    inBoxItems = inBoxItems.Restrict("[Unread] = true");
    try
    {
        foreach (object collectionItem in inBoxItems)
        {
            newEmail = collectionItem as Outlook.MailItem;
            if (newEmail != null)
            {
                if (newEmail.Attachments.Count > 0)
                {
                    for (int i = 1; i <= newEmail
                       .Attachments.Count; i++)
                    {
                        newEmail.Attachments[i].SaveAsFile
                            (@"C:\TestFileSave\" +
                            newEmail.Attachments[i].FileName);
                    }
                }
            }
        }
    }
    catch (Exception ex)
    {
        string errorInfo = (string)ex.Message
            .Substring(0, 11);
        if (errorInfo == "Cannot save")
        {
            MessageBox.Show(@"Create Folder C:\TestFileSave");
        }
    }