I am trying to extract email metadata from messages in an Outlook Exchange account. I derive various metadata as described here, but I can't get the name of the folder where the email has been stored.
What I have so far:
Clear-Host
$outlook = New-Object -Com Outlook.Application
$mapi = $outlook.GetNamespace('MAPI')
$mailboxRoot = $mapi.GetDefaultFolder([Microsoft.Office.Interop.Outlook.OlDefaultFolders]::olFolderInbox).Parent
$walkFolderScriptBlock = {
param(
$currentFolder
)
foreach ($item in $currentFolder.Folders) {
$item.Items
}
}
$Email = & $walkFolderScriptBlock $mailboxRoot
$Results = $Email | Select ConversationTopic, ReceivedTime;
$Results | Export-Csv -Path C:\Temp\2024-01-25EmailTesting.csv
I tried variants of the word "folder" following the word "Select". It returns an empty column.
Update - @mhu has made a breakthrough and gotten the names of folders. When I run their script, I see folders like "Delete" and "Inbox". Which is a major step forward, but am wondering if I could also get the subfolders under "Inbox" (i.e. "Accessibility Committee" and "Advisory").
You can select the parent name property like this:
(and you don't need the script block, unless you want to recursively process the folders)
$results = @()
$outlook = New-Object -Com "Outlook.Application"
$mapi = $outlook.GetNamespace("MAPI")
$mailboxRoot = $mapi.GetDefaultFolder([Microsoft.Office.Interop.Outlook.OlDefaultFolders]::olFolderInbox).Parent
$folders = $mailboxRoot.Folders | Select-Object -ExpandProperty "Items"
foreach ($folder in $folders)
{
$results += $folder |
Where-Object { $_.Class -eq 43 } |
Select-Object -Property "ConversationTopic", "ReceivedTime", @{ "Label" = "Folder"; "Expression" = { $_.Parent.Name } }
}
$results | Export-Csv -Path "C:\Temp\email.csv"
Example output:
ConversationTopic ReceivedTime Folder
----------------- ------------ ------
This week at Humble: Mega Man franchise pack & more! 10/02/2024 16:16:58 Test
Advanced example for processing nested folders:
Set-StrictMode -Version "Latest"
$ErrorActionPreference = "Stop"
function Get-MailFromOutlookFolder
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[Object] $ParentFolder
)
$items = @()
foreach ($folder in $ParentFolder.Folders)
{
foreach ($item in ($folder | Select-Object -ExpandProperty "Items"))
{
if ($item.Class -eq 43)
{
# process email
$items += $item | Select-Object -Property "ConversationTopic", "ReceivedTime", @{ "Label" = "Folder"; "Expression" = { $_.Parent.Name } }
}
}
# process (sub)folder items
$items += Get-MailFromOutlookFolder -ParentFolder $folder
}
return $items
}
$outlook = New-Object -Com "Outlook.Application"
$mapi = $outlook.GetNamespace("MAPI")
$mapi.GetDefaultFolder([Microsoft.Office.Interop.Outlook.OlDefaultFolders]::olFolderInbox).Parent
$results = Get-MailFromOutlookFolder -ParentFolder $mailboxRoot
$results | Export-Csv -Path "C:\Temp\email.csv"