Processing mails in MS Outlook with PowerShell
1. Plain text mails
Let’s say we have a mail with the following content:

# we will use this function to parse the input strings (rows):
function ProcessPlainTextMail
{
Param ($myParam1)
$myVar = $myParam1.Body | % { (($_ -split ("`r`n"))[0] -replace "Country: ", "").Trim() }
$myVar1
# output:
# Austria
$myVar2 = $myParam1.Body | % { (($_ -split ("`r`n"))[3] -replace "Date: ", "").Trim() | % { if($_.Contains(".")){[datetime]::ParseExact($_,'dd. MM. yyyy HH:mm', [System.Globalization.CultureInfo]::GetCultureInfo('de-DE'))}else{[datetime]::ParseExact($_,'M/d/yyyy h:mm tt', [System.Globalization.CultureInfo]::GetCultureInfo('en-EN'))} }}
$myVar2
# output:
# Tuesday, January 24, 2023 5:30:00 PM
$myVar3 = $myParam1.Body | % { (($_ -split ("`r`n"))[4] -replace "Date: ", "").Trim() | % { if($_.Contains(".")){[datetime]::ParseExact($_,'dd. MM. yyyy HH:mm', [System.Globalization.CultureInfo]::GetCultureInfo('de-DE'))}else{[datetime]::ParseExact($_,'M/d/yyyy h:mm tt', [System.Globalization.CultureInfo]::GetCultureInfo('en-EN'))} }}
$myVar3
# output:
#Tuesday, January 24, 2023 5:30:00 PM
# set mail to "Read":
$myParam1.UnRead = $false
# and move it to another folder (e. g. Trash):
$myParam1.Move($myTargetFolderOfProcessedMails) | Out-Null
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($HTML) | Out-Null
}PowerShellTIP
The MS Outlook app must be running when executing this script!
First we have to specify where the mails are:
# the name of the mailbox to check:
$myMailBox = "AdminTips"
# this is the folder where we read the mails from:
$myFolderToCheck = "Test1"
# after processing the mails we move them into this folder:
$moveTo = "Test2"
$myOutlook = New-Object -ComObject Outlook.Application
$myNameSpace = $myOutlook.GetNamespace('MAPI')
$myStore = $myNameSpace.Stores[$myMailBox]
$myRootFolder = $myStore.GetRootFolder()
$mySubFolder = $myRootFolder.Folders($myFolderToCheck)
$myTargetFolderOfProcessedMails = $myRootFolder.Folders($moveTo)
# -> it must be an object: we can't just say 'Hey move it to the folder Test2!'
PowerShellThen we can call our function:
# starting from 1! -> that's the first items index (the first mail in the folder)
for($i = 1; $i -le $mySubFolder.Items.Count; $i++)
{
ProcessPlainTextMail $mySubFolder.Items.Item($i)
}
PowerShell2. HTML mails
In this case we have a mail with a table like this:

# we will use this function to parse the data in the HTML table in the e-mail:
function ProcessHTMLMail
{
Param ($myParam1)
$HTML = New-Object -ComObject "HTMLFile"
$HTML.IHTMLDocument2_write($myParam1.HTMLBody)
$temp = $HTML.IHTMLDocument2_all.tags("td") | % innerText
# $i+=4 because we have 4 columns in the table: we're reading rows
for($i = 0; $i -lt $temp.Length; $i+=4)
{
if($temp[$i].Trim() -eq "")
{
break
}else{
[datetime]::ParseExact($temp[$i].Trim(), 'dddd, d. MMMM yyyy hh:mm tt', [System.Globalization.CultureInfo]::GetCultureInfo("en-EN"))
$temp[$i + 1]
$temp[$i + 2]
$temp[$i + 3]
}
}
# set mail to "Read":
$myParam1.UnRead = $false
# and move it to another folder (e. g. Trash):
$myParam1.Move($myTargetFolderOfProcessedMails) | Out-Null
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($HTML) | Out-Null
}
PowerShellHere we have to specify a couple of things too:
# the name of the mailbox to check:
$myMailBox = "AdminTips"
# this is the folder where we read the mails from:
$myFolderToCheck = "Test1"
# after processing the mails we move them into this folder:
$moveTo = "Test2"
$myOutlook = New-Object -ComObject Outlook.Application
$myNameSpace = $myOutlook.GetNamespace('MAPI')
$myStore = $myNameSpace.Stores[$myMailBox]
$myRootFolder = $myStore.GetRootFolder()
$mySubFolder = $myRootFolder.Folders($myFolderToCheck)
$myTargetFolderOfProcessedMails = $myRootFolder.Folders($moveTo)
# -> it must be an object: we can't just say 'Hey move it to the folder Test2!'PowerShellThen we can call our function for the HTML mails:
# starting from 1! -> that's the first items index (the first mail in the folder)
for($i = 1; $i -le $mySubFolder.Items.Count; $i++)
{
ProcessHTMLMail $mySubFolder.Items.Item($i)
}PowerShellEither way, in the end we have to clean up:
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($myOutlook) | Out-Null
PowerShell
