Get .msg Copy by Criteria 'PR_INTERNET_MESSAGE_ID'

33 views Asked by At

This post serves as an open collaboration forum

Pretext:

Outlook (v2038) and Exchange (5.5) have a couple of built-in ways to search messages for a User's and Admin's view using specific criteria such as Subject, Sender, Recipient, etc; but to my knowledge, both Outlook and Exchange do not have a built-in way to search messages by using a message's Internet Message ID.

That said, I'm attempting to create a Powershell script to first locate a message by the Message ID, then copy the .msg to a target folder. (Tools like Outlook Spy exist that more than likely are able to do this, but tools as such cannot be used in all environments)

Script Goal:

  • Locate and Copy multiple messages from any user's mailbox to an admin's mailbox by using a message's Internet Message ID

Note: a User script is being created first to mitigate performance impacts to an active Exchange server

Note: The below works on PSv7.4 and PSv5.1 tested on Outlook 2016 (v2038)

WIP User Script (As of 03/05/2024):

# Loads Assemblies 
$Interop = "C:\Program Files\Microsoft Office\root\Office16\ADDINS\Microsoft Power Query for Excel Integrated\bin\Microsoft.Office.Interop.Outlook.dll"
Add-type -AssemblyName "$Interop" | Out-Null
$Outlook = New-Object -ComObject Outlook.Application
$MAPI = $Outlook.GetNamespace("MAPI")

# Loads the Current Outlook Session Default Mailbox (Inbox)
$olDefaultFolderInbox = 6
$Inbox = $MAPI.GetDefaultFolder($olDefaultFolderInbox)

# Defines the Current Outlook Session Target Mailbox
$olFolderName = "Test Folder"
$TargetFolder = $Inbox.Folders | Where-Object {
     $_.Name -eq $olFolderName
}

# Gets the 'PR_INTERNET_MESSAGE_ID' of All Emails Within the Target Mailbox
$Emails = $TargetFolder.Items
$TargetEmails = foreach ( $Emails in $Emails ) {
     $Emails.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x007D001E")
}

# Defines the Target Header
$TargetHeaderCriteria = "<[email protected]>"

# Searches the Target Mailbox Emails (.Items) for an Email that contains the Matching Target Header
$MAPIResults = $TargetEmails | Where-Object {$_.contains($TargetHeaderCriteria)}
# Outputs the Matching Target Header
$MAPIResults

So far I've been able to create the above to search by Message ID within a specified mailbox, but I'm having difficulties formulating / implementing a solution for a User to be able to now get that specific message they've tracked down (whether that be copying the .msg to a target folder, or extracting the .msg to a directory).

('$MAPIResults' variable serves to a be future callable variable)

QUESTION:

Powershell gurus, if you find the time, I'd love your aid in creating this :)

1

There are 1 answers

0
Dmitry Streblechenko On

There is absolutely no reason to loop through all emails in a folder collecting all message ids, let the store provider do the heavy lifting: use Items.Find/FindNext or Items.Restrict. Since it is expected that there is only a single match for a given id, a single call to Items.Find should do the job:

In VBA. http://schemas.microsoft.com/mapi/proptag/0x1035001F is the DASL property name of the PR_INTERNET_MESSAGE_ID MAPI property:

messageid = "<[email protected]>"
set targetFolder = Application.Session.GetDefaultFolder(olFolderDeletedItems)
set inbox =  Application.Session.GetDEfaultFolder(olFolderInbox)
set TargetFolder = inbox.Folders("Stash")
set match = TargetFolder.Items.Find("@SQL=""http://schemas.microsoft.com/mapi/proptag/0x1035001F"" = '" & messageid &"' ")
if match Is Nothing Then
  Debug.Print "Message not found"
else
  Debug.Print "Found: " & match.Subject
End If