Use this code sample and function to display the Internet header of selected message in a new message form.
Tested in Outlook 2013, 2019, 2021, and Outlook 365, also works in Outlook 2010 and 2007.
The PowerShell version does not require you to change Outlook security settings. to use, select one or more messages then run the script.
clear $olApp = new-object -comobject outlook.application $PropName = "http://schemas.microsoft.com/mapi/proptag/0x007D001E" $olFolder = ($olApp.ActiveExplorer()) $Selection = $olFolder.Selection foreach ($olMsg in $Selection) { $oPA = $olMsg.PropertyAccessor $value = $oPA.GetProperty($PropName) $Mail = $olApp.CreateItem(0) $ndatetime = Get-Date -Format g $Mail.Subject = $olMsg.subject + ' ' +$ndatetime $Mail.Body = $value $Mail.display() }
Save it as a *.ps1 then right-click and choose Run with PowerShell.
Or create a shortcut and pin it to the taskbar or Start menu. The target will be
powershell.exe -file "C:\path\to\filename.ps1"
Note: Windows will add the full path to powershell.exe to the shortcut.
VBA method to get message header
Sub ViewInternetHeader() Dim olItem As Outlook.MailItem, olMsg As Outlook.MailItem Dim strheader As String For Each olItem In Application.ActiveExplorer.Selection strheader = GetInetHeaders(olItem) Set olMsg = Application.CreateItem(olMailItem) With olMsg .BodyFormat = olFormatPlain .Body = strheader .Display End With Next Set olMsg = Nothing End Sub Function GetInetHeaders(olkMsg As Outlook.MailItem) As String ' Purpose: Returns the internet headers of a message.' ' Written: 4/28/2009' ' Author: BlueDevilFan' ' //techniclee.wordpress.com/ ' Outlook: 2007' Const PR_TRANSPORT_MESSAGE_HEADERS = "http://schemas.microsoft.com/mapi/proptag/0x007D001E" Dim olkPA As Outlook.PropertyAccessor Set olkPA = olkMsg.PropertyAccessor GetInetHeaders = olkPA.GetProperty(PR_TRANSPORT_MESSAGE_HEADERS) Set olkPA = Nothing End Function
Write the header to a text file
This version of the above macro writes the header to a text file and opens it in Notepad. (You'll need the Function GetInetHeaders from above).
If you want to open it in another Text application, replace "notepad " with the file path and name, making sure to leave the space after the filename.
Sub ViewInternetHeader() Dim olItem As Outlook.MailItem, olMsg As Outlook.MailItem Dim strheader As String For Each olItem In Application.ActiveExplorer.Selection strheader = GetInetHeaders(olItem) ' ### write to a text file Dim FSO As Object Dim strFile As String Dim strFolderpath As String Set FSO = CreateObject("Scripting.FileSystemObject") ' save to documents strFolderpath = CreateObject("WScript.Shell").SpecialFolders(16) strFile = strFolderpath & "\header.txt" Set objFile = FSO.CreateTextFile(strFile, True) ' True overwrites the file Debug.Print strFile objFile.Write "" & strheader objFile.Close Call Shell("notepad.exe " & strFile, vbNormalFocus) ' ### end write to text file Next Set olMsg = Nothing End Sub
Get Specific Values from the header
But combining RegEx and the macro above we can get specific values out of the header. In this example, we're getting the address in the Return-Path.
If you need two or more values, you'll use a Case statement to loop through the header. See Get two (or more) values from a message for an example.
Sub GetValuesFromInternetHeader() Dim olItem As Outlook.MailItem, olMsg As Outlook.MailItem Dim strHeader As String Dim strResult As String Dim strResults As String Dim Reg1 As Object Dim M1 As Object Dim M As Object For Each olItem In Application.ActiveExplorer.Selection strHeader = GetInetHeaders(olItem) Set Reg1 = CreateObject("VBScript.RegExp") With Reg1 .Pattern = "(Return-Path:\s(.*))" .Global = True End With If Reg1.test(strHeader) Then Set M1 = Reg1.Execute(strHeader) For Each M In M1 ' 0 = everything in the first set of () ' 1 = everything in the second set of () Debug.Print M.SubMatches(0) strResult = M.SubMatches(1) ' do something with the result strResults = strResult & vbCrLf & vbCrLf & strResults Next End If Next Set olMsg = Application.CreateItem(olMailItem) With olMsg .BodyFormat = olFormatPlain .Body = strResults .Display End With Set olMsg = Nothing End Sub Function GetInetHeaders(olkMsg As Outlook.MailItem) As String ' Purpose: Returns the internet headers of a message.' ' Written: 4/28/2009' ' Author: BlueDevilFan' ' //techniclee.wordpress.com/ ' Outlook: 2007' Const PR_TRANSPORT_MESSAGE_HEADERS = "http://schemas.microsoft.com/mapi/proptag/0x007D001E" Dim olkPA As Outlook.propertyAccessor Set olkPA = olkMsg.propertyAccessor GetInetHeaders = olkPA.GetProperty(PR_TRANSPORT_MESSAGE_HEADERS) Set olkPA = Nothing End Function
Send a Spam Report
If you need to send a spam report to your ISP, you can use a macro to automate it. This macro will work on one message or a selection of messages.
If the macro is not creating a body that can be processed by the reporting service, try changing the 0x007D001E value to 0x007D001F. This returns PR_TRANSPORT_MESSAGE_HEADERS_W instead of PR_TRANSPORT_MESSAGE_HEADERS. See Geldner's thread and answer here: Problem submitting SPAM using Outlook VBA Form
Sub ForwardSpam() Dim olItem As Outlook.MailItem, olMsg As Outlook.MailItem Dim strHeader As String Dim strFWHeader As String Dim strNote As String For Each olItem In Application.ActiveExplorer.Selection strHeader = GetInetHeaders(olItem) strNote = "boilerplate note, if needed" Set olMsg = olItem.Forward With olMsg .To = "report@address.com" .BodyFormat = olFormatPlain .Body = strNote & vbCrLf & vbCrLf & strHeader & vbCrLf & vbCrLf & olItem.Body .Display ' change to .send when satisfied End With olItem.Delete Next Set olMsg = Nothing End Sub Function GetInetHeaders(olkMsg As Outlook.MailItem) As String ' Purpose: Returns the internet headers of a message.' ' Written: 4/28/2009' ' Author: BlueDevilFan' ' //techniclee.wordpress.com/ ' Outlook: 2007' Const PR_TRANSPORT_MESSAGE_HEADERS = "http://schemas.microsoft.com/mapi/proptag/0x007D001E" Dim olkPA As Outlook.propertyAccessor Set olkPA = olkMsg.propertyAccessor GetInetHeaders = olkPA.GetProperty(PR_TRANSPORT_MESSAGE_HEADERS) Set olkPA = Nothing End Function
Using PowerShell Scripts
To use PowerShell scripts with Outlook, start typing PowerShell on the start menu and open Windows PowerShell when it comes up. Windows PowerShell ISE has a script pane at the top, which is useful if you want to edit the script.
Paste the entire script in the PowerShell window and press Enter or the Run button if using PowerShell ISE.
Note: PowerShell scripts will not work with new Outlook or Outlook on the web.
Saving PowerShell Scripts
If you want to save the script as a .ps1 file, paste it into Notepad and save it with the extension .ps1. To open it in the PowerShell IDE, type PowerShell on the start menu and click on Windows PowerShell IDE when the PowerShell app is found. Paste the script in the editing window.
To use it, you need to allow local scripts by running this command:
Set-ExecutionPolicy RemoteSigned
To run your saved .ps1 file, right-click on the script and choose Run with PowerShell.
How to use macros
First: You will need macro security set to low during testing.
To check your macro security in Outlook 2010 or 2013, go to File, Options, Trust Center and open Trust Center Settings, and change the Macro Settings. In Outlook 2007 and older, it’s at Tools, Macro Security.
After you test the macro and see that it works, you can either leave macro security set to low or sign the macro.
Open the VBA Editor by pressing Alt+F11 on your keyboard.
To put the code in a module:
- Right click on Project1 and choose Insert > Module
- Copy and paste the macro into the new module.
More information as well as screenshots are at How to use the VBA Editor
More Information
Retrieving Internet Headers Using VBA in Outlook 2007/2010 Includes a code sample to use with Run a Script rule.
For Outlook 2003 and older, see Get Internet header VBA code sample for Outlook 2003.
It would be nice to be able to get a specific part of the Internet Headers, for instance the Reply-To adress, and to display it in a new column (custom view). Very useful against spoofing ! I have tried to design a custom form for this purpose... but to no avail...
That is possible, using propertyaccessor or regex to find a value in the header.
https://www.slipstick.com/developer/read-mapi-properties-exposed-outlooks-object-model/
https://www.slipstick.com/developer/code-samples/outlooks-internet-headers/#values
use .Pattern = "(Reply-To:\s(.*))"
Is there an easy way to mod the Spam Report macro so that it strips any blank lines from the header when creating the email report? Outlook, for some reason, often creates blank lines in headers and it causes SPAMCOP.NET to choke.
this is excellent.
How do I create a text file with the exact same information as the email that the 1st macro made?
Use this in place of the code that creates a message in the first macro
wow, thanks.
very helpful.
So much information! Wow.
Is there any way to filter the header and only write the date/time received to the text file? Is there a way to break out each piece of information, like recipient?, sender?
Are all of these 'Objects'?
You can get anything out of the header using regex, but the common fields are in vba - receivedtime, subject, sendername and senderemailaddress, recipient all are stored in fields accessible by VBA.
Get the fields, then write the strings to the text file.
With olItem
strName = .SenderName
strSender = .SenderEmailAddress
strTime = .ReceivedTime
End With
I just figured out that it'll work..... just not with a user form.
Would you be willing to modify it to work with a user form, or to put an output into a user form/label on a form?
Hi.
In trying the code for the first one above, I get a run time error on the
.display under the With operation.
It tells me that it cannot perform that operation because a dialogue box is open, and needs to be closed. I have two dialogues open.
1- the program itself.
2- the user form I've created. I close the user form, and it still throws the error.
I'm using office 365.
Thank you.
Supercallifragilisticexpialidocious
Well done. Thank's a lot!
Dear Diane,
Thanks for your code . would you please me , i want to add some condition to code after extraction of few details. such as ; Reply To; From; To; and etc.
please help me to add some condition on it.
Thanks in advance.
Dear Diane,
Thanks for your code . it was really helpful to me . in the email headers i was trying to remove particular line from every header.
"h=sender:from:reply-to:to:subject:mime-version:content-type:list-unsubscribe:x-report-abuse:form-sub;"
please help me to find solution on this .
you'll change the pattern to find it...
.Pattern = "(h=(.*)-sub)"
Do you actually need to remove it from the header or need to copy it out of the header? VBA can't edit the internet header - you may be able to use Redemption (outlookspy.com) to edit it but i don't have code samples. If the line nver changes, you can use the replace function to remove it.
Dear Diane,
Thanks for response,
From the header i am extracting few details , such as;
.Pattern = "(To:\s(.*))"
but in result i am getting this , as both Contains To: ,
can u help to get exact match of string what i am searching . as code is not understanding that i am looking only for "To" not
"Reply-to."
Reply-To: Jon Luchette
To: Ernie Bourassa