Skip to content

Instantly share code, notes, and snippets.

@bill-long
Last active January 24, 2021 14:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bill-long/09545eae085f9da0886b to your computer and use it in GitHub Desktop.
Save bill-long/09545eae085f9da0886b to your computer and use it in GitHub Desktop.
Search Exchange Server mailboxes for items with a specific subject via EWS Managed API.
#########################################
# SearchMailboxesViaEWS.ps1
#
# The -InputFile should point to a text file that contains an email address
# on each line, with nothing else. For example:
#
# user1@contoso.com
# user2@contoso.com
# ...
#
param(
[Parameter(Mandatory=$true,Position=1)]
[string]$InputFile,
[Parameter(Mandatory=$false,Position=2)]
[boolean]$DeleteSearch
)
#########################################
# Update the path below to match the actual path to the EWS managed API DLL.
# Can be downloaded at: http://www.microsoft.com/en-us/download/details.aspx?id=42951
#
Import-Module -Name "C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll"
#
#########################################
#########################################
#
$searchFolderName = "SearchMailboxesViaEWS"
$subjectToSearchFor = "RE: Test 2"
$useImpersonation = $true
#
#########################################
if ($InputFile -eq "")
{
"A file containing a list of mailboxes must be specified."
return
}
$mailboxList = Get-Content $InputFile
if ($mailboxList.Count -eq $null)
{
# Some versions of Powershell don't return a collection if there's
# only one line in the file.
if ($mailboxList -ne $null -and $mailboxList.Length -gt 0)
{
$mailboxList = ,$mailboxList
}
}
("Number of mailboxes to process: " + $mailboxList.Count.ToString())
if ($mailboxList.Count -lt 1)
{
return
}
$exchService = new-object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010)
$exchService.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
foreach ($emailAddress in $mailboxList)
{
$exchService.AutoDiscoverUrl($emailAddress, {$true})
if ($useImpersonation)
{
$exchService.ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $emailAddress)
}
$mbx = new-object Microsoft.Exchange.WebServices.Data.Mailbox($emailAddress)
$topOfInformationStore = [Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot
$topOfInformationStoreId = new-object Microsoft.Exchange.WebServices.Data.FolderId($topOfInformationStore, $mbx)
$topOfInformationStoreFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($exchService, $topOfInformationStoreId)
if ($topOfInformationStoreFolder -eq $null)
{
("Error. Could not open mailbox: " + $emailAddress)
continue
}
$searchFolders = [Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::SearchFolders
$searchFoldersId = new-object Microsoft.Exchange.WebServices.Data.FolderId($searchFolders, $mbx)
$searchFoldersFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($exchService, $searchFoldersId)
if ($searchFoldersFolder -eq $null)
{
("Error. Could not bind to search folders folder: " + $emailAddress)
continue
}
"Opened mailbox: " + $emailAddress
# see if the search folder already exists
$folderView = new-object Microsoft.Exchange.WebServices.Data.FolderView(2147483647)
$subfolders = $searchFoldersFolder.FindFolders($folderView)
$mySearchFolder = $null
foreach ($subfolder in $subfolders)
{
if ($subfolder.DisplayName -eq $searchFolderName)
{
$mySearchFolder = $subfolder
break
}
}
if ($DeleteSearch)
{
if ($mySearchFolder -ne $null)
{
$mySearchFolder.Delete([Microsoft.Exchange.WebServices.Data.DeleteMode]::HardDelete)
"Deleted search folder from mailbox: " + $emailAddress
}
else
{
"Search folder not present in mailbox: " + $emailAddress
}
continue
}
if ($mySearchFolder -eq $null)
{
$newSearchFolder = New-Object Microsoft.Exchange.WebServices.Data.SearchFolder($exchService)
$searchCriteria = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.ItemSchema]::Subject, $subjectToSearchFor)
$newSearchFolder.SearchParameters.SearchFilter = $searchCriteria
$newSearchFolder.SearchParameters.RootFolderIds.Add($topOfInformationStoreId)
$newSearchFolder.SearchParameters.Traversal = [Microsoft.Exchange.WebServices.Data.SearchFolderTraversal]::Deep
$newSearchFolder.DisplayName = $searchFolderName
$errCount = $error.Count
$newSearchFolder.Save([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::SearchFolders)
$mySearchFolder = $newSearchFolder
if ($errCount -eq $error.Count)
{
"Search folder created."
}
else
{
continue
}
}
$itemView = new-object Microsoft.Exchange.WebServices.Data.ItemView(100)
while (($folderItems = $mySearchFolder.FindItems($itemView)).Items.Count -gt 0)
{
foreach ($item in $folderItems)
{
$parentFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($exchService, $item.ParentFolderId)
"Found item in folder: " + $parentFolder.DisplayName + " with subject: " + $item.Subject
}
$offset += $folderItems.Items.Count
$itemView = new-object Microsoft.Exchange.WebServices.Data.ItemView(100, $offset)
}
}
"Done!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment