How to search for emails in a non standard exchange folder using EWS and powershell

瘦欲@ 提交于 2019-12-24 12:17:44

问题


I want use powershell and EWS (see https://msdn.microsoft.com/en-us/library/office/dd633710(v=exchg.80).aspx) to search for emails that contain a particular string in the subject line.

My problem is that the emails reside in a user-defined folder in the inbox, rather than in one of the folders listed in the WellKnownFolderName enumeration (see https://msdn.microsoft.com/en-us/library/microsoft.exchange.webservices.data.wellknownfoldername(v=exchg.80).aspx)

The example code that I have found to search for emails all wants to search in one of these well-known folder names rather than in an arbitrary user-specified folder.

does anyone have some example code that i can use as a reference to figure out how to do this [or does EWS limit you to searching for emails using a well-known folder name only].

My code so far is thus:

$email    = "myemail@someplace.com"
$username = "myusername" 
$password = "*****"
$domain   = "mydomain"
$USER_DEFINED_FOLDER_IN_MAILBOX = "myRandomFolder"

$EXCHANGE_WEB_SERVICE_DLL = "C:\Program Files (x86)\Microsoft\Exchange\Web Services\1.2\Microsoft.Exchange.WebServices.dll"
# load the assembly
[void] [Reflection.Assembly]::LoadFile($EXCHANGE_WEB_SERVICE_DLL)

# set ref to exchange
$s = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService

# use first option if you want to impersonate, otherwise, grab your own credentials
$s.Credentials = New-Object Net.NetworkCredential($username, $password, $domain)

# discover the url from your email address
$s.AutodiscoverUrl($email)

# get a handle to the inbox
$inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox)

$MailboxRootid = new-object  Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Root, $email) # selection and creation of new root
$MailboxRoot = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s,$MailboxRootid)

$fvFolderView = new-object Microsoft.Exchange.WebServices.Data.FolderView(100) #page size for displayed folders
$fvFolderView.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep; #Search traversal selection Deep = recursively
$SfSearchFilter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::Displayname,$NAME_OF_ARCHIVE_FOLDER_IN_MAILBOX) #for each folder in mailbox define search
$findFolderResults = $MailboxRoot.FindFolders($SfSearchFilter,$fvFolderView) 

$ArchiveFolder = ""

# This next loop successfully finds my folder, but it is an inefficient way 
# to do it.  It's ok, because there's not that many folders, but there's tens 
# of thousands of emails to search through in the folder itself, and that will
# need a more efficient search.
foreach ($Fdr in $findFolderResults.Folders)
{
    $theDisplayName = $Fdr.DisplayName
    if($theDisplayName -eq $USER_DEFINED_FOLDER_IN_MAILBOX)
    {
        $ArchiveFolder = $Fdr
    }
}

# Now to actually try and search through the emails in my $ArchiveFolder (the hard way)
$textToFindInSubject = "TEST"

$emailsInFolder = $ArchiveFolder.FindItems(9999)   # <-- Successfully finds ALL emails with no filtering, requiring iterative code to find the ones I want.
foreach($individualEmail in $emailsInFolder.Items)
{
    if($individualEmail.Subject -match "$textToFindInSubject")
    {       
        # found the email i want -  but a super inefficient
        # way to do it
        echo "Successfully found the email!"
    }
}

# Attempt 1 to get the emails with a more refined search
$emailSearchFilter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+ContainsSubstring([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::Subject,$textToFindInSubject) 
$emailsInFolder1 = $ArchiveFolder.FindItems($emailSearchFilter)  # <-- Fails to return an object

# Attempt 2 to get the emails with a more refined search
$iv = new-object Microsoft.Exchange.WebServices.Data.ItemView(2000)
$emailsInFolder2 = $s.FindItems($ArchiveFolder,  $emailSearchFilter, $iv)   # <-- Also fails to return an object

echo "Done."

Thanks heaps :-)


回答1:


I figured it out. Here are the lines of code that work [when appended to the initial code]

$searchfilter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+ContainsSubstring([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::Subject,$textToFindInSubject)     
$itemView = new-object Microsoft.Exchange.WebServices.Data.ItemView(999)
$searchResults = $s.FindItems($ArchiveFolder.ID, $searchfilter, $itemView)

foreach($result in $searchResults)
{
    $subj = $result.Subject

    echo "Subject: $subj"
}



回答2:


This EWS script lists all folders, including custom ones. I'm running this on our Exchange 2010 SP1 server:

Import-Module -Name "C:\Program Files\Microsoft\Exchange Server\V14\ClientAccess\Owa\Bin\Microsoft.Exchange.WebServices.dll"
$userEmail = "email.address@domain.com"

$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP2)
$service.UseDefaultCredentials = $true
$service.AutoDiscoverUrl($userEmail)

$view = New-Object Microsoft.Exchange.WebServices.Data.FolderView(100)
$view.PropertySet = New-Object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.Webservices.Data.BasePropertySet]::FirstClassProperties)
$view.PropertySet.Add([Microsoft.Exchange.Webservices.Data.FolderSchema]::DisplayName)
$view.Traversal = [Microsoft.Exchange.Webservices.Data.FolderTraversal]::Deep

$findResults = $service.FindFolders([Microsoft.Exchange.Webservices.Data.WellKnownFolderName]::MsgFolderRoot, $view)

# List all folders
$findResults | select displayname


来源:https://stackoverflow.com/questions/41499533/how-to-search-for-emails-in-a-non-standard-exchange-folder-using-ews-and-powersh

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!