Connect to Office 365 using PowerShell v2

Introduction

If you ever run into a situation where you would like to connect to Office 365 but you do not have a modern version of PowerShell at your disposal, you may consider the following approach.

Disclaimer

The following approach won’t work for SharePoint Online since it is not possible to access SharePoint Online with “app-only” authentication. If you do need to access SharePoint Online with “app-only” authentication, you’ll need to either

  • Create your application secret using a certificate
  • Link your Azure AD application registration with a SharePoint-Addin (with permissions to access SharePoint Online “offline” i.e. without user interaction)

Alternatively, you could implement a somewhat “hacky” workaround in the form of an Azure Function that would get the data you need from SharePoint Online. You could then add a “functional” user instead. I will come back to this “recipe” in a future blog post.

Obtain an access token

When you’re hands are tied and you cannot use the rich set of PnP PowerShell Cmdlets then you’ll notice that you cannot connect using Connect-PnPOnline. So you’ll need to get your hands dirty and go and obtain an access (bearer) token yourself. To continue, you must have previously registered an Azure AD app and created a secret for it (see the official Microsoft documentation)[https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-integrating-applications].

# Read the following settings from your environment e.g. XML or console input
$settings = @{
    AADAppId        = <# The application ID of your Azure AD app registration #>
    AADAppSecret    = <# The application secret of your Azure AD app registration #>
    AADTenantID     = <# The directory ID of your Azure AD #>
}

# Get Access Code

$authorizeUrl = "https://login.microsoftonline.com/$($settings.AADTenantID)/oauth2/token"

# Cast body as byte array
$body = [byte[]][char[]]"grant_type=client_credentials&client_id=$($settings.AADAppId)&client_secret=$($settings.AADAppSecret)&resource=https%3A%2F%2Fgraph.microsoft.com%2F.default";

$req = [System.Net.WebRequest]::Create($authorizeUrl)
$req.Method = "POST"
$req.ContentType = "application/x-www-form-urlencoded"
$req.ContentLength = $body.Length

# Write the request body
$bodyWriter = $req.GetRequestStream()
$bodyWriter.Write($body, 0 , $body.Length)
$bodyWriter.Dispose()

# Get the response and convert it to json
$res = $req.GetResponse()
$stream = $res.GetResponseStream()
$reader = New-Object System.IO.StreamReader $stream
$data = ConvertFrom-Json($reader.ReadToEnd()) # TODO Some error handling
$reader.Dispose()

<# Expected $data looks like

Key            Value
---            -----
token_type     Bearer
expires_in     3600
ext_expires_in 0
expires_on     1520781595
not_before     1520777695
resource       https://graph.microsoft.com/default
access_token   eyJ0eXAiOiJKV1QiLCJhbGciOiJS... 

#>

Use the access token

Now you can use the access token to make subsequent web requests and add an authorization header e.g. as folllows…

$req = [System.Net.WebRequest]::Create(<# Your target URL goes here #>)
$req.Method = "GET"
$req.Headers.Add("Authorization", "Bearer $($data.access_token)")
...

You May Also Like

Leave a Reply

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

%d bloggers like this: