FunctionsPublic/Get-GraphAccessTokenByCode.ps1

<#
.SYNOPSIS
Get AAD Access Token
 
.DESCRIPTION
Function uses a Client ID and Client Secret in combination with an Authorization Code to authenticate against a specific AAD tenant and obtains an access token.
#>

function Get-GraphAccessTokenByCode 
{
    [CmdletBinding()]
    param
    (
        [string]$tenantID,
        [string]$clientID,
        [string]$clientSecret,
        [string]$redirectURI,
        [string]$authorizationCode
    )

    process 
    {
        $baseURL = "https://login.microsoftonline.com/$($tenantID)/oauth2/v2.0/token"
        
        $Body = @(
            'grant_type=authorization_code'
            '&redirect_uri={0}' -f [System.Web.HttpUtility]::UrlEncode($redirectURI)
            '&client_id={0}' -f [System.Web.HttpUtility]::UrlEncode($clientID)
            '&code={0}' -f [System.Web.HttpUtility]::UrlEncode($authorizationCode)
            '&client_secret={0}' -f [System.Web.HttpUtility]::UrlEncode($clientSecret)
            '&scope=https://graph.microsoft.com/.default'
        ) -join ''

        Write-Debug "Body: $Body"

        $RequestedDate = Get-Date
        $Params = @{
            Uri = $BaseURL
            Method = 'POST'
            ContentType = "application/x-www-form-urlencoded"
            Body = $Body
            ErrorAction = 'Stop'
            SessionVariable = 'Session'
        }

        try {
            Write-Debug "Retrieving OAuth Access Token from $BaseURL..."
            $Result = Invoke-WebRequest @Params
        }
        catch {
            $_.Exception.
                psobject.
                TypeNames.
                Insert(0,'MSGraphAPI.Oauth.Exception')
            Write-Error -Exception $_.Exception
            return
        }
        try {
            $Content = $Result.Content | ConvertFrom-Json -ErrorAction Stop
        }
        Catch {
            $Params = @{
                MemberType = 'NoteProperty'
                Name = 'Respone'
                Value = $Result
            }
            $_.Exception | Add-Member @Params
            Write-Error -Exception $_.Exception
            return
        }

        $SecureAccessToken = $Content.access_token | ConvertTo-SecureString -AsPlainText -Force
        $AccessTokenCredential = [pscredential]::new('access_token', $SecureAccessToken )
        
        #
        # Construct 'AccessToken' object
        #
        @{
            Application = $Application
            AccessTokenCredential = $AccessTokenCredential
            RequestedDate = $RequestedDate
            Response = $Content | Select-Object -property * -ExcludeProperty access_token, refresh_token
            ResponseHeaders = $Result.Headers
            LastRequestDate = $RequestedDate
            Session = $Session
            GUID = [guid]::NewGuid()
        }
    }
}