问题
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