(Ab)using the REST API endpoints behind the new ExO cmdlets

Anyone that’s running admin tasks in Exchange Online is probably aware that a new, “V2” module has been released, featuring some faster and much more reliable cmdlets (in case you aren’t, watch this Ignite session). Those are backed by REST API endpoints, similar to the Graph API that covers most other workloads in Office 365. While Exchange Online is yet to support the Graph (or should it be the other way around?), the new REST endpoints can be exploited in a similar manner, as long as you know what you’re doing. Let’s see how.

First things first, you need to authenticate and in order to do that you need a token. To obtain a token, you must specify few bits of information, such as the clientID and resource, all of which you can obtain by running a Fiddler trace or in some cases by crawling the sign-in logs. Once you have all the details, you can either use the ADAL/MSAL binaries or directly issue a web request to obtain the token. I find it easier to use the former approach, so here’s a code snippet that loads the corresponding binaries and calls the AcquireTokenAsync method:

Add-Type -Path 'C:\Program Files\WindowsPowerShell\Modules\AzureAD\2.0.1.10\Microsoft.IdentityModel.Clients.ActiveDirectory.dll' 

$authContext3 = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList "https://login.windows.net/michev.onmicrosoft.com"

$plat = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.PlatformParameters -ArgumentList "Auto"

$authenticationResult = $authContext3.AcquireTokenAsync("https://outlook.office365.com", "fb78d390-0c51-40cd-8e17-fdbfab77341b", "urn:ietf:wg:oauth:2.0:oob",$plat);

Once you get the token, you can issue standard web requests against the corresponding endpoints. And in case you are wondering which endpoint you need and the exact syntax to use, you can easily obtain this information by running the corresponding new cmdlet with the -Debug switch. Here’s an example:

And here’s an example on how to get a list of all the mailboxes via the REST endpoint:

$authHeader = @{'Authorization'=$authenticationResult.Result.CreateAuthorizationHeader()}

$mailboxes = Invoke-RestMethod -Method Get -Uri "https://outlook.office.com/adminApi/beta/xxxxxxxx-352a-4eda-bece-09d0684d0cfb/Mailbox" -Headers $AuthHeader

$mailboxes.value

As another example, we can get the properties for a single mailbox:

Invoke-RestMethod -Method Get -Uri "https://outlook.office.com/adminApi/beta/xxxxxxxx-352a-4eda-bece-09d0684d0cfb/Mailbox('vasil@xxxxxx.info')" -Headers $AuthHeader 

@odata.context : https://outlook.office.com/adminApi/beta/xxxxxxxx-352a-4eda-bece-09d0684d0cfb/$metadata#Mailbox/$entity
@odata.id : https://outlook.office.com/adminApi/beta/xxxxxxxx-352a-4eda-bece-09d0684d0cfb/Mailbox(xxxxxxxx-888c-4b85-8871-c9766cb4791b')
@odata.editLink : https://outlook.office.com/adminApi/beta/xxxxxxxx-352a-4eda-bece-09d0684d0cfb/Mailbox(xxxxxxxx-888c-4b85-8871-c9766cb4791b'
ExternalDirectoryObjectId : xxxxxxxx-888c-4b85-8871-c9766cb4791b
UserPrincipalName : vasil@xxxxxx.info
Alias : vasil
DisplayName : Vasil Michev
EmailAddresses : {smtp:vasil@sb1.xxxxxx.info, SPO:SPO_xxxxxxxx-e473-451a-85e9-097d3c08307e@SPO_xxxxxxxx-352a-4eda-bece-09d0684d0cfb, SIP:vasil@xxxxxx.info, smtp:vasil@xxxxxx.onmicrosoft.com...}
PrimarySmtpAddress : vasil@xxxxxx.info
RecipientType : UserMailbox
RecipientTypeDetails : UserMailbox
Identity : vasil
Id : vasil
ExchangeVersion : 0.20 (15.0.0.0)
Name : vasil
DistinguishedName : CN=vasil,OU=michev.onmicrosoft.com,OU=Microsoft Exchange Hosted Organizations,DC=EURPR03A001,DC=prod,DC=outlook,DC=com
OrganizationId : EURPR03A001.prod.outlook.com/Microsoft Exchange Hosted Organizations/michev.onmicrosoft.com - EURPR03A001.prod.outlook.com/ConfigurationUnits/michev.onmicrosoft.com/Configuration
Guid : xxxxxxxx-4e45-4c28-a80f-b57b7441490f

And so on. Now, it goes without saying that this method is not supported in any way, so you should not use it in production. But, the samples above illustrate the inner workings of the new cmdlets, and they also hint what you can expect from the future Graph API endpoints for Exchange Online. To get more details on this as well as other tips on using the new cmdlets, join me and fellow MVP Ingo Gegenwarth on February 5th for the Working with the new Exchange Cmdlets webinar.

This entry was posted in Exchange Online, Office 365. Bookmark the permalink.

2 Responses to (Ab)using the REST API endpoints behind the new ExO cmdlets

  1. oded mass says:

    Hi, Is it possible to use the api with client_credentials grant_type.
    If so how can we set the api permissions for the application?
    Thanks.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.