[EWS]Using Oauth authentication with EWS in Office 365

I’m sharing a PowerShell script sample that illustrates using Oauth authentication via Azure Active Directory (AAD) and EWS to connect to Office 365 mailbox. The script outputs the total item count in Inbox folder and prints the subject of the last five items in Inbox. The authorization grant flow used is Authorization code grant flow which means the user gives assent to the app to access his own mailbox.

There are couple of blogs I’m referring below that helped in putting up this script.

1. For loading Active Directory Authentication Library
https://www.dushyantgill.com/blog/2013/12/27/aadgraphpowershell-a-powershell-client-for-windows-azure-ad-graph-api/

2. Acquiring the token
https://blogs.technet.com/b/keithmayer/archive/2014/12/30/authenticating-to-the-azure-service-management-rest-api-using-azure-active-directory-via-powershell-list-azure-administrators.aspx

Please note that the application registered in AAD is a native client application (not a web app). For detailed steps related to manual app registration in AAD, please see this article. The permission provided is Exchange scope permissions (Delegated permissions under Office 365 Exchange Online): full_access_as_user – Access mailbox as signed in user via Exc…”

 

EWS permission in AAD

 #NOTE - Disclaimer
 #Following programming examples is for illustration only, without warranty either expressed or implied,
 #including, but not limited to, the implied warranties of merchantability and/or fitness for a particular purpose.
 #This sample code assumes that you are familiar with the programming language being demonstrated and the tools
 #used to create and debug procedures. This sample code is provided for the purpose of illustration only and is
 #not intended to be used in a production environment.
 
 # Load ADAL Assemblies
 
 $adal = "C:\Nugets\Microsoft.IdentityModel.Clients.ActiveDirectory.2.19.208020213\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
 
 $adalforms = "C:\Nugets\Microsoft.IdentityModel.Clients.ActiveDirectory.2.19.208020213\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll"
 
 [System.Reflection.Assembly]::LoadFrom($adal)
 
 [System.Reflection.Assembly]::LoadFrom($adalforms)
 
 # Set Azure AD Tenant name; not used in this script
 
 $adTenant = "domain.onmicrosoft.com"
 
 # Set well-known client ID from Azure AD for this application
 # It is in the form of a guid 1a2b34c5-da6b-7777-ef8a-g9h001i23456
 
 $clientId = "client-id"
 
 # Set redirect URI from Azure AD for this application
 #e.g https://myapp/reply
 
 $redirectUri = "reply-url"
 
 # Set Resource URI to Office 365 in this case
 
 $resourceAppIdURI = "https://outlook.office365.com/"
 
 # Set Authority to Azure AD Tenant
 #https://stackoverflow.com/questions/26384034/how-to-get-the-azure-account-tenant-id
 
 $authority = "https://login.windows.net/<tenant-id>/oauth2/authorize"
 
 # Create Authentication Context tied to Azure AD Tenant
 
 $authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority
 
 # Acquire token
 
 $authResult = $authContext.AcquireToken($resourceAppIdURI, $clientId, $redirectUri, "Auto")
 
 ## Code From https://poshcode.org/624
 ## Create a compilation environment
 $Provider=New-Object Microsoft.CSharp.CSharpCodeProvider
 $Compiler=$Provider.CreateCompiler()
 $Params=New-Object System.CodeDom.Compiler.CompilerParameters
 $Params.GenerateExecutable=$False
 $Params.GenerateInMemory=$True
 $Params.IncludeDebugInformation=$False
 $Params.ReferencedAssemblies.Add("System.DLL") | Out-Null
 
 $TASource=@'
   namespace Local.ToolkitExtensions.Net.CertificatePolicy{
     public class TrustAll : System.Net.ICertificatePolicy {
       public TrustAll() {
       }
       public bool CheckValidationResult(System.Net.ServicePoint sp,
         System.Security.Cryptography.X509Certificates.X509Certificate cert,
         System.Net.WebRequest req, int problem) {
         return true;
       }
     }
   }
 '@
 $TAResults=$Provider.CompileAssemblyFromSource($Params,$TASource)
 $TAAssembly=$TAResults.CompiledAssembly
 
 ## We now create an instance of the TrustAll and attach it to the ServicePointManager
 $TrustAll=$TAAssembly.CreateInstance("Local.ToolkitExtensions.Net.CertificatePolicy.TrustAll")
 [System.Net.ServicePointManager]::CertificatePolicy=$TrustAll
 
 Import-Module -Name "C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll"
 
 $service = new-object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP2)
 
 $service.Url = new-object System.Uri("https://outlook.office365.com/ews/exchange.asmx")
 
 $service.Credentials  = new-object  Microsoft.Exchange.WebServices.Data.OAuthCredentials($authResult.AccessToken)
 
 $inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service, [Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox)
 ""
 "Total items in Inbox : " + $inbox.TotalCount
 $view = New-Object Microsoft.Exchange.WebServices.Data.ItemView(5)
 $findItemResults = $service.FindItems([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox,$view)
 ""
 
 "Printing subject of last five items from Inbox:"
 
 ""
 $item = [Microsoft.Exchange.WebServices.Data.Item]
 
 $i = 1
 
 foreach ($item in $findItemResults)
 {
 "Subject " + $i + ": " + $item.Subject
 $i = $i + 1
 ""
 }

Read more about EWS and Oauth authentication here.

Happy scripting!