How to access body of Outlook email messages from Powershell script?
Solution 1
Based upon the MSDN documentation I believe that this is indeed the Anti-virus blocking access to selective properties via the Object Model Guard. This explains why the $mm.Body
property is settable but not gettable. Since I do not have access to any of the corporate security settings on my machine I was unable to pursue the interop direction any further.
There are a few workaround suggestions
- Exchange Web Services - Which are available via the EWS API (.Net binding of the web service.)
- Extended MAPI - a Native library interface.
- A Third party COM wrapper of the Extended MAPI interface. (such as Redemption)
I think I will be working with the EWS although I have to say that the interface is rather complicated.
thanks to @TessellatingHeckler for point me on the path.
Solution 2
With the following code you access the body of the unread mails in the file named "mailFolder".
$OL=New-Object -ComObject OUTLOOK.APPLICATION
$ns =$OL.GETNAMESPACE("MAPI")
[string]$Folder ="mailFolder"
$mail = $ns.Folders.Item(1).Folders.Item($Folder).Items.Restrict('[UnRead] = True')
$mail | Select-Object -Property Body | Format-List
Solution 3
well, I have multiple accounts in my outlook. I have slightly customized the code shared by Mr. MahmutKarali and it worked for me. Also, the code runs in non-admin mode of PowerShell only. After that, I have to allow access in the outlook app on my desktop for 10 mins.
$ol = New-Object -ComObject Outlook.Application
$ol.Session.Logon("Outlook")
$ns = $ol.GetNamespace("MAPI")
$mail = $ns.Folders.Item(3).Folders.Item(2).Items.Restrict('[UnRead] = True')
$mail | Select-Object -Property Body | Format-List
Here Item(3) is for getting a specific user from profiles and Item(2) is for getting the inbox folder for that user. It's all hit and trial for me to fnd these values, it can vary for you so just run the code step by step and part by part to get the desired folder of your user. I hope this helps.
nickdmax
Updated on November 26, 2020Comments
-
nickdmax over 3 years
I have a basic folder in my outlook with alerts from a monitoring system. I would like to create a table based upon that data. To that end I have been trying to access the body content of emails in Outlook:
Add-Type -Assembly "Microsoft.Office.Interop.Outlook" $Outlook = New-Object -ComObject Outlook.Application $namespace = $Outlook.GetNameSpace("MAPI") $inbox = $namespace.GetDefaultFolder([Microsoft.Office.Interop.Outlook.OlDefaultFolders]::olFolderInbox) $inbox.Items | Format-Table BodyFormat, Body, HTMLBody, RTFBody
Now I would expect to see some content for Body, HTMLBody, or RTFBody -- I do not. I DO see that BodyFormat is most often 2 (olFormatHTML). So most of the emails should have content in HTMLBody -- None of them do. I can access the subject lines but not the content.
Since every example I find online seems to be able to get the body content I think it must be a setting in outlook to only download the subject lines or something. We have Enterprise Vault -- could the content be stored separate from the message?
-
nickdmax almost 8 yearsso If I set $mm to the first message
$mm=$inbox.items.getfirst()
then I can see that$mm.downloadstate
is 1 which should mean fully downloaded. -- So I don't think outlook is just getting the subject lines. Still$mm.body
and$mm.HTMLBody
are empty. -
nickdmax almost 8 years
$mm.GetInspector.EditorType
returns 4 or (olEditorWord). But that did not seem to lead anywhere. I can SET the body$mm.body="this is a test"
-- but still$mm.body
is empty BUT the message is displayed in outlook. -
TessellatingHeckler almost 8 yearsWorks for me here, lists email body content. I get the feeling your problem isn't PowerShell and is somewhere else in your setup. Reaching a bit, but could it be an AntiVirus/AntiMalware client blocking scripts from accessing Outlook? Is there any way you could approach accessing your mailbox by script through Exchange Web Access (or Exchange Web Services) instead of through Outlook?
-
nickdmax almost 8 yearsI think you are right, I think there is something blocking the COM interface - however I can find no documentation of such a feature. Another theory I have is versions -- When I run the script without Outlook open, then try to open Outlook it tells me that "Another version of Outlook is running..." SO - maybe the reason I am unable to access some COM objects is that the library Powershell loaded is newer/older than the version of Outlook installed. maybe.
-
nickdmax almost 8 yearsWell, the Assembly says that version is 14.0.0.0 which should be Outlook 2010. Just to be safe I tried both 32 and 64bit PowerShell modules. I also attempted running as Admin. No change.
-
nickdmax almost 8 yearsIn the past, I have had no luck with EWS due to Autodiscover, BUT I just discovered that if I do an internal search it works (basically if I don't try to "login"). So... well there we go.
-
-
nickdmax about 7 yearsThis still does not work for me. I can view the subjects:
$ns.Folders.Item(1).Folders.Item("inbox").Items | Select-Object -Property Subject
but I can not view the body of the emails - that was the central problem. I have since abandoned this task as it seems that there are security measures in place to prevent a script from accessing the content of emails on our system. I did look into using the EWS API but the work did not get very far as the interface was a bit too complicated for quick scripts.