如何使用EWS和powershell在非标准交换文件夹中搜索电子邮件

时间:2017-01-06 05:33:48

标签: powershell exchangewebservices

我想使用powershell和EWS(请参阅https://msdn.microsoft.com/en-us/library/office/dd633710(v=exchg.80).aspx)来搜索主题行中包含特定字符串的电子邮件。

我的问题是电子邮件驻留在收件箱中的用户定义文件夹中,而不是在WellKnownFolderName枚举中列出的其中一个文件夹中(请参阅https://msdn.microsoft.com/en-us/library/microsoft.exchange.webservices.data.wellknownfoldername(v=exchg.80).aspx

我发现搜索电子邮件的示例代码都希望搜索其中一个知名文件夹名称而不是用户指定的任意文件夹。

是否有人拥有一些示例代码,我可以将其用作参考,以确定如何执行此操作[或者EWS是否限制您仅使用知名文件夹名称搜索电子邮件]。

到目前为止,我的代码是:

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

谢谢堆: - )

2 个答案:

答案 0 :(得分:0)

我明白了。以下是[附加到初始代码时]

的代码行
$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"
}

答案 1 :(得分:0)

此EWS脚本列出了所有文件夹,包括自定义文件夹。我在Exchange 2010 SP1服务器上运行它:

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