Search code examples
powershelloutlookextractmetadataoffice-automation

Extract the name of the folder housing an email


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").

enter image description here

enter image description here


Solution

  • 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"