Lead Image © Paul Herbert, 123RF.com

Lead Image © Paul Herbert, 123RF.com

Exchange Web Services for Mailbox Access

Mail Manager

Article from ADMIN 60/2020
Exchange Web Services (EWS) is an important interface that lets applications access Exchange content. You can access the EWS mailbox via PowerShell or create your own tools.

Most administrators are familiar with the Exchange Web Services from the virtual directories and as a means for Outlook to publish out-of-office messages. But the services can do much more and provide useful functions such as sorting out attachments. In this article, we look at EWS mailbox access via PowerShell and possibilities for in-house development.

Exchange Web Services (EWS) is an important interface that lets applications access Exchange content. Outlook uses the services to call the availability service and the Out of Office Wizard, among other things. Exchange has been using EWS since version 2007, which is the basic prerequisite for using the corresponding API. In addition, you need the Exchange Web Services Managed API 2.2 [1].

If you only use Exchange locally, the EWS API is available as described below. However, Microsoft 365 previously had different interfaces for the different tools. For Exchange, it was the EWS interface presented here, among others.

In the future, Microsoft Graph will serve as the central access point for the interaction of the various services in Microsoft 365. However, it is not directly available for a local Exchange and only in hybrid environments will you be able to access local Exchange environments via Microsoft Graph. Furthermore, EWS will no longer receive function updates in Exchange Online [2].

Disabling Exchange Basic Authentication

For Exchange, basic authentication was, for a long time, a fast way to log on – always active and easy to use. However, it offers a greater potential for attack, and additional security mechanisms such as multi-factor authentication are often not used because of their complexity.

For this reason, Microsoft decided as early as 2018 to switch off basic authentication for EWS at Exchange Online as of October 2020. In 2019, the provider extended this shutdown to Exchange ActiveSync (EAS), POP, IMAP, and Remote PowerShell. Due to COVID-19, the deadline has now been postponed to the second half of 2021. In the future, logon will be based on state-of-art authentication with Active Directory Authentication Library (ADAL) and OAuth 2.0 [3].

Getting Started with Exchange Web Services

Since Exchange 2007, Microsoft has recommended using the same name range for internal and external connections. The "mail.domain.com" name is all it takes for client access to all the servers in an environment.

You can change the names of the access points in the Exchange Administration Center by going to Servers/Virtual Directories . Another way to set up the URLs is to use the PowerShell with the Set-WebServicesVirtualDirectory cmdlet and the InternalUrl and ExternalUrl parameters. Make sure that these URLs are also stored in the certificate, and try to limit the number of names to as few as possible.

To access data, you need a user account with appropriate rights for the mailboxes. For Exchange, assign the corresponding "ApplicationImpersonation" role to a user with the following command:


"Impersonation" means that the process pretends to be the corresponding user and works in their context. Alternatively, you can create a corresponding role in the EAC and assign it to the service user (Figure 1).

Figure 1: The Impersonation role is used to grant a process access to the mailbox in the context of the user.

Using PowerShell with the EWS Managed API

The EWS Managed API can also be accessed directly via PowerShell. As an example, we will be downloading the attachments of an email. This functionality is also used by many archive providers who remove attachments via EWS and exchange them for an archive link. Also conceivable in this context is processing role mailboxes and downloading attachments for further processing.

In Listing 1, we first define the variables. Here we need the path to the WebServices.dll for the Managed API 2.2, which we will use to define the mailbox with the folder to be checked, along with the access credentials. To use the operators, the script loads the API DLL using the Import-Module cmdlet, which makes various operators available [4].

Listing 1

Sort Out Email Attachments

01 [string]$DllPath = "C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll"
02 [string]$Mailbox = "groupmail@example.com"
03 [string]$Password = "CS%Outlook2020"
04 [string]$Domain = "schulenburg"
05 [string]$EWSURL = "https://outlook.office365.com/EWS/Exchange.asmx"
06 [string]$DownloadPath = "C:\Temp\Attachments"
07 [string]$Folder = "Inbox"
08 Import-Module -Name $DllPath
09 $ExchangeService = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2007_SP1)
10 $ExchangeService.Credentials = New-Object Microsoft.Exchange.WebServices.Data.WebCredentials($Mailbox,$Password,$Domain)
11 $ExchangeService.Url = $EwsURL
12 $offset = 0
13 Do {
14    $ItemView = New-Object Microsoft.Exchange.WebServices.Data.ItemView(1000, $offset)
15    $ItemView.PropertySet = New-Object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
16    $Items = $ExchangeService.FindItems([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]:: $Folder,$ItemView)
17   $Items
18    foreach ($Item in $Items)
19    {
20     If ($Item.HasAttachments -eq $true)
21     {
22      Write-Host "Subject: $($Item.Subject)" -ForegroundColor cyan
23     $PropertySet = New-Object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange. WebServices.Data.ItemSchema]::Attachments)
24      $Message = [Microsoft.Exchange.WebServices.Data.EmailMessage]::Bind($ExchangeService, $Item.Id,$PropertySet)
25      Foreach ($Attachment in $Message.Attachments)
26      {
27        $AttachmentName = $Attachment.Name
28        If ($AttachmentName -match ".pdf")
29        {
30         $AttachmentName
31         $Attachment.Load("$DownloadPath\$AttachmentName")
32        }
33      }
34    }
35 }
36     $offset = $offset + 1000
37  } while($Items.MoreAvailable)

Once the DLL is loaded, we have access to the WebServices.Data.ExchangeService name range and can use the New-Object cmdlet to create a new object to connect to EWS. A specific version of Exchange is not necessary nor does it have to match the version of your server. It only defines the lowest supported version.

The EWS-API offers different possibilities to determine access points. This can be done by an autodiscover of the domain or simply by a fixed assignment like in our example (ExchangeService.Url = $EwsURL").

Various options are also available for authentication. To simplify matters, we stored the login data in the script, which you should generally avoid in production use.

$ExchangeService.Credentials = New-Object Microsoft.Exchange.WebServices.Data.WebCredentials($Mailbox,$Password,$Domain)

Alternatively, you can use the currently logged in user as follows:

$ExchangeService.UserDefaultCredentials = $true

In our example, we first discovered the emails from the specified mailbox using FindItems. The result is then checked for attachments with the property HasAttachments. And, in the foreach loop, the document type is checked before the attachments are downloaded. As a result, all PDF attachments of emails end up in the Inbox in the folder C:\ Temp\Attachments .

The script can now be extended further, and the processed emails could easily be moved to another suborder using the Move method (in the script $Item.Move ("DeletedItems")). You can find an overview of the options on the Exchange website [5], and the template for our sample script on the Icewolf blog [6].

Basic functions like writing a log or sending an email to the administrator are possible independently of EWS. Another example is clearing all emails older than 30 days from the trash. This is an interesting option for any mailbox, and you can find a template on the Icewolf blog [7].

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus
Subscribe to our ADMIN Newsletters
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs

Support Our Work

ADMIN content is made possible with support from readers like you. Please consider contributing when you've found an article to be beneficial.

Learn More”>


		<div class=