I'm trying to convert some existing Exchange Online EWS scripts to use Oauth. I'm able to request an access token, but when I try to work with a mailbox it errors with the following. I appreciate your help!
x-ms-diagnostics: 2000003;reason="The audience claim value is invalid for current resource. Audience claim is 'https://graph.microsoft.com', request url is 'https://outlook.office365.com/EWS/ Exchange.asmx' and resource type is 'Exchange'.";error_category="invalid_resource"
Here's the code:
## Request an access token
# Define AppId, secret and scope, your tenant name and endpoint URL
$AppId = 'APP-ID HERE'
$AppSecret = 'SECRET HERE'
$Scope = "https://graph.microsoft.com/.default"
$TenantName = "OurDomain.onmicrosoft.com"
$Url = "https://login.microsoftonline.com/$TenantName/oauth2/v2.0/token"
# Add System.Web for urlencode
Add-Type -AssemblyName System.Web
# Create body
$Body = @{
client_id = $AppId
client_secret = $AppSecret
scope = $Scope
grant_type = 'client_credentials'
}
# Splat the parameters for Invoke-Restmethod for cleaner code
$PostSplat = @{
ContentType = 'application/x-www-form-urlencoded'
Method = 'POST'
# Create string by joining bodylist with '&'
Body = $Body
Uri = $Url
}
# Request the token!
$Request = Invoke-RestMethod @PostSplat
#######################
# Import "Microsoft Exchange Web Services Managed API 2.2"
Import-Module -Name "C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll"
## Create the Exchange Service object with Oauth creds
$Service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService -ArgumentList Exchange2013_SP1
$service.Url= new-object Uri("https://outlook.office365.com/EWS/Exchange.asmx")
$Service.TraceEnabled = $true
$Service.Credentials = New-Object Microsoft.Exchange.WebServices.Data.OAuthCredentials($Request.access_token)
#####################
$Email = "UserA@OurDomain.com"
# Set the WellKnownFolder
$FolderId = [Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox
# Bind to WellKnownFolder Notes
$folder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($Service, $folderId)
Write-Host "$($Email): $($folderName): " -NoNewline
$folder.archivetag.RetentionId.Guid
In your script you will need to change the scope original scope from
$Scope = "https://graph.microsoft.com/.default"
to
$Scope = "https://outlook.office365.com/.default"
The rest of your code isn't using the Graph so you don't need to get an access token for something your not using. Also because your using an App Secret you would be generating an App Only token which means you won't have a refresh token anyway. The two things that is missing from your EWS code is you need to use EWS Impersonation and you should also always set the X-AnchorMailbox header eg you would have
$service.HttpHeaders.Add("X-AnchorMailbox", "mailboxtoaccess@domain.com")
$service.ImpersonatedUserId = new-object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, "mailboxtoaccess@domain.com")