Using PowerShell and the Office 365 REST API with OAuth.

Who is this blog post for:

Administrators who want to use PowerShell to query Office 365 Rest API using OAuth.

Who isn't this for?

Anyone who uses any other programming language -
Check out this getting started - it's perfect for you:
https://dev.office.com/getting-started/office365apis

So... Let's get started

This is also a good time to recommend a really useful tool written by my colleague that allows you to experiment with the OAuth API:
https://github.com/Microsoft/Office365APIEditor

I've also used a method to show a nice UI window for the login window I found through:
https://foxdeploy.com/2015/11/02/using-powershell-and-oauth/
I recommend reading this - the explanations here are very simple.
I'm basically covering just the implementation in that blog.

Code for the method is directly accessible here:
https://raw.githubusercontent.com/1RedOne/PSWordPress/master/Private/Show-oAuthWindow.ps1 but I made a few modifications to it.

Scripting Guy's blog regarding OAuth and Windows Live:
https://blogs.technet.microsoft.com/heyscriptingguy/2013/07/01/use-powershell-3-0-to-get-more-out-of-windows-live/

My motivation for writing this blog:

I've lately been hearing more and more about the Office 365 REST API from customers who are using it with OAuth and needed to get started with using it.
I also need to do quick verifications and script things quickly and for that PowerShell is just awesome.
PowerShell was missing from the getting-started guide and I've been wanting to try it out for a while.

Step 1:
The first thing we want to is to register a new app:

Sign in with your Office 365 account here.
https://dev.office.com/app-registration

Step 2:
In the App registration page go ahead and register an app.
App name - you can name it whatever you want.
App type - for the purpose of this blog - we can use Web App
Sign on and Redirect URI - for the purposes of this tutorial you can just leave them as is.

Click Register app.
You'll get a client-id and client-secret.
Copy paste everything on this page to a text file, we're going to use it later.

Time to start scripting!

Now that we have that, we can get started with the script.

First thing we want to do is define our very handy Show-OAuthWindow method:

 Function Show-OAuthWindow
{
    param(
        [System.Uri]$Url
    )


    Add-Type -AssemblyName System.Windows.Forms
 
    $form = New-Object -TypeName System.Windows.Forms.Form -Property @{Width=440;Height=640}
    $web  = New-Object -TypeName System.Windows.Forms.WebBrowser -Property @{Width=420;Height=600;Url=($url ) }
    $DocComp  = {
        $Global:uri = $web.Url.AbsoluteUri
        if ($Global:Uri -match "error=[^&]*|code=[^&]*") {$form.Close() }
    }
    $web.ScriptErrorsSuppressed = $true
    $web.Add_DocumentCompleted($DocComp)
    $form.Controls.Add($web)
    $form.Add_Shown({$form.Activate()})
    $form.ShowDialog() | Out-Null

    $queryOutput = [System.Web.HttpUtility]::ParseQueryString($web.Url.Query)
    $output = @{}
    foreach($key in $queryOutput.Keys){
        $output["$key"] = $queryOutput[$key]
    }
    
    $output
}

What does it do? It just opens the URL we want in a handy little window. Then we use the response to parse a few parameters.

Below this, we can define our variables and the System.Web assembly.

 Add-Type -AssemblyName System.Web
$client_id = "paste the client ID we generated"
$client_secret = "paste the client secret we got"
$redirectUrl = "the redirect URL we used when creating the app."

We can then create our login URL:

 $loginUrl = "https://login.microsoftonline.com/common/oauth2/authorize?response_type=code&redirect_uri=" + 
            [System.Web.HttpUtility]::UrlEncode($redirectUrl) + 
            "&client_id=$client_id" + 
            "&prompt=login"

If you're wondering how I knew the format of the request, everything is documented here:
https://graph.microsoft.io/en-us/docs/authorization/app_authorization

Then we'll go ahead and use the method above:

 $queryOutput = Show-OAuthWindow -Url $loginUrl

We need to enter the username and password we're going to use with this app.
Once we do that, we'll get a page asking us to approve the APP access to the permissions we specified above - so we can go ahead and approve that.

$queryOutput will have the following keys in the hashtable:
code
session_state

The code is what we're interested in - as we're going to go ahead and trade it for an access token.
How are we going to do that?
Well, we're going to make another request:

 
$AuthorizationPostRequest = 
    "grant_type=authorization_code" + "&" +
    "redirect_uri=" + [System.Web.HttpUtility]::UrlEncode($redirectUrl) + "&" +
    "client_id=$client_id" + "&" +
    "client_secret=" + [System.Web.HttpUtility]::UrlEncode("$client_secret") + "&" +
    "code=" + $queryOutput["code"] + "&" +
    "resource=" + [System.Web.HttpUtility]::UrlEncode("https://outlook.office.com/")

Then we can go ahead and make the request:

 $Authorization = 
    Invoke-RestMethod   -Method Post `
                        -ContentType application/x-www-form-urlencoded `
                        -Uri https://login.microsoftonline.com/common/oauth2/token `
                        -Body $AuthorizationPostRequest

After execution $Authorization will have our very handy access_token - which we now have to add to every call we make.

Let's see an example:

 $mail = 
    Invoke-RestMethod   -Headers @{Authorization =("Bearer "+ $Authorization.access_token)} `
                        -Uri https://outlook.office.com/api/v2.0/me/messages `
                        -Method Get

Now we can look at our mail variable:

 $mail.value | select -first 4 | select -ExpandProperty Subject 

That's it!
If you have any questions, let me know :-)