How to query Outlook from PowerShell

Harnessing PowerShell to Query Outlook: A Productivity Boost for Your Inbox

In the digital age, email has become an indispensable communication tool. For many professionals, Microsoft Outlook serves as the go-to platform for managing emails, calendars, and contacts. While Outlook provides a user-friendly interface, extracting specific information or automating tasks can be time-consuming. In this article, we'll explore the power of PowerShell and how you can leverage it to write a script that queries Outlook, boosting productivity and streamlining your inbox management.

The Power of PowerShell

PowerShell is a versatile scripting language and automation framework developed by Microsoft. It is a core component of the Windows operating system and provides a rich set of commands to interact with various services and applications. When it comes to Outlook, PowerShell enables you to perform complex operations and obtain valuable insights with just a few lines of code.

Why Query Outlook from PowerShell?

Querying Outlook through PowerShell offers numerous benefits, including:

Automation: PowerShell scripts can automate repetitive tasks in Outlook, such as organizing emails, forwarding messages, or creating calendar events, saving valuable time and effort.

Customization: The ability to query Outlook allows you to tailor your email management system according to your specific needs, ensuring an efficient workflow.

Data Analysis: PowerShell can extract and process email data, enabling you to perform analytics and gain insights into your communication patterns.

Integration: By combining PowerShell with other tools and systems, you can create powerful cross-platform automation solutions.

Writing a PowerShell Script to Query Outlook

The following SearchOutlook.ps1 script allows you to query emails from the inbox folder in Outlook using multiple optional arguments:

Text: string contained in the body of the emails.

Subject: string contained in the subject of the emails.

From: sender of the emails.

DateReceived: reception date of the oldest emails that can be included in the result of the query.


$OfficeAssemblyFile = (get-childitem $env:windir\assembly -Recurse office.dll | Select-Object -first 1).FullName
$OutlookAssemblyFile = (get-childitem $env:windir\assembly -Recurse Microsoft.Office.Interop.Outlook.dll | Select-Object -first 1).FullName
Add-Type -Path $OfficeAssemblyFile
Add-Type -Path $OutlookAssemblyFile

$outlook = [Microsoft.Office.Interop.Outlook.ApplicationClass]::new()
$namespace = $outlook.GetNamespace("MAPI");

Register-ObjectEvent -InputObject $outlook -EventName AdvancedSearchComplete -Action {
    write-host `n $Args.Scope
    if ($Args.Results) {  
        foreach ($result in $Args.Results) {
            write-host $result.ReceivedTime "|" $result.SenderName "|" $result.Subject
        }
    }
    Get-Job | Stop-Job
    Get-Job | Remove-Job
}

Function AddFilter {
  param (
    [string]$filter,
    [string]$newFilter
  )
  if ([System.String]::IsNullOrEmpty($filter) -eq $false){
      $filter += " AND "
  }
  $filter += $newFilter

  return $filter
}

Function SearchOutlook {
    [CmdletBinding()]
    param (  
        [Parameter(Mandatory=$false)]
        [string]$Text = $null,
        [Parameter(Mandatory=$false)]
        [string]$Subject = $null,
        [Parameter(Mandatory=$false)]
        [string]$From = $null,
        [Parameter(Mandatory=$false)]
        [string]$DateReceived = $null
    )

    if ([System.String]::IsNullOrEmpty($Text) -eq $false){
        $newFilter = "urn:schemas:httpmail:textdescription LIKE '%"+$Text+"%'"
        $filter = AddFilter $filter $newFilter
    }
    if ([System.String]::IsNullOrEmpty($Subject) -eq $false){
        $newFilter = "urn:schemas:httpmail:subject LIKE '%"+$Subject+"%'"
        $filter = AddFilter $filter $newFilter
    }
    if ([System.String]::IsNullOrEmpty($From) -eq $false){
        $newFilter = "urn:schemas:httpmail:sender LIKE '%"+$From+"%'"
        $filter = AddFilter $filter $newFilter
    }
    if ([System.String]::IsNullOrEmpty($DateReceived) -eq $false){
        $datareceived = Get-Date $DateReceived
        $newFilter = "urn:schemas:httpmail:datereceived >= '"+$datareceived+"'"
        $filter = AddFilter $filter $newFilter
    }
    $accountsList = $namespace.GetDefaultFolder([Microsoft.Office.Interop.Outlook.OlDefaultFolders]::olFolderInbox)
    $searchSubFolders = $True
    foreach($account in $accountsList) {
        $scope = $account.FolderPath
        $search = $outlook.AdvancedSearch("'$scope'", $filter, $searchSubFolders)
    }
}

SearchOutlook @args


This script uses the publish/subscribe mechanism of the PowerShell jobs. It is run in an independent asynchronous job, so that you can continue doing other things. And when the query finishes, it prints out the results.

Asynchronous Job
Asynchronous Job

Wrapping the script in a batch file

Similarly to the technique shown in the article How to use the Windows Search Index from PowerShell, we can create a batch file that will allow us to run the SearchOutlook.ps1 script from the Windows Run dialog. That way, we can quickly look for emails containing a specific text with a fast key combination.

We can create the following search-outlook.bat script as a wrapper of the SearchOutlook.ps1 script:


@echo off

Rem Description: Search email with specified text in Outlook Inbox
Rem Usage: search-outlook.bat <string>
Rem Example: search-outlook.bat SCCF

set cmd="SearchOutlook.ps1 -Text '%*'"
echo %cmd%

PowerShell -NoExit -ExecutionPolicy Bypass -Command %cmd%

Once we have it ready, it is just a matter of adding its location to the Path environment variable. And then, we could just run it pressing Win+R and typing the text that we want to search in our emails.

Windows Run dialog
Windows Run dialog

Conclusion

PowerShell is a powerful tool to harness the potential of Outlook by writing custom scripts that can automate repetitive tasks, analyze data, and streamline your email management. This article only scratches the surface of what is possible with PowerShell and Outlook integration. As you delve deeper into PowerShell scripting, you'll find endless possibilities for enhancing your productivity and efficiency in handling emails and other tasks.

Popular posts from this blog

How to setup NeoVim configuration file

WebAssembly (Wasm): Fixing the Flaws of Applets