FunctionsPublic/Get-GraphAuthorizationCode.ps1

<#
.SYNOPSIS
Get AAD Authorization Code
 
.DESCRIPTION
Function to obtain an Autorization Code on behalf of a user from AAD.
#>

function Get-GraphAuthorizationCode 
{
    [CmdletBinding()]
    param
    (
        [string]$tenantID,
        [string]$clientID,
        [string]$redirectURI
    )
    
    process 
    {
        [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") 
        [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") 

        $baseURL = "https://login.microsoftonline.com/$($tenantID)/oauth2/v2.0/authorize"

        # ForcePrompt = none / login / consent / admin_consent
        $forcePrompt = "login"

        if ($forcePrompt -ne "") 
        {
            $forcePromptURI = "&prompt=$($forcePrompt)"
        }

        $Url = "$($baseURL)?response_type=code&redirect_uri=$($redirectURI)&client_id=$($clientID)$($forcePromptURI)&scope=https://graph.microsoft.com/.default"

        Write-Verbose "URL: '$URL'"
        $Params = @{
            TypeName = 'System.Windows.Forms.Form'
            Property = @{
                Width = 440
                Height = 640
            }
        }
        $Form = New-Object @Params
        $Params = @{
            TypeName = 'System.Windows.Forms.WebBrowser'
            Property = @{
                Width = 420
                Height = 600
                Url = $Url
            }
        }
        $Web = New-Object @Params
        $DocumentCompleted_Script = {
            if ($web.Url.AbsoluteUri -match "error=[^&]*|code=[^&]*") {
                $form.Close()
            }
        }

        # ScriptErrorsSuppressed must be $false or AD FS tenants will fail on Windows Integrated Authentication pages
        $web.ScriptErrorsSuppressed = $false
        $web.Add_DocumentCompleted($DocumentCompleted_Script)
        $form.Controls.Add($web)
        $form.Add_Shown({ $form.Activate() })
        [void]$form.ShowDialog()

        $QueryOutput = [System.Web.HttpUtility]::ParseQueryString($web.Url.Query)
        $Response = @{ }
        foreach ($key in $queryOutput.Keys) {
            $Response["$key"] = $QueryOutput[$key]
        }
        $SecAuthCode = 'NOAUTHCODE' | ConvertTo-SecureString -AsPlainText -Force
        $AuthCodeCredential = [pscredential]::new('NOAUTHCODE', $SecAuthCode)
        if ($Response.Code) {
            $SecAuthCode = $Response.Code | ConvertTo-SecureString -AsPlainText -Force
            $AuthCodeCredential = [pscredential]::new('AuthCode', $SecAuthCode)
            $Response.Remove('Code')
        }

        [pscustomobject]@{
            PSTypeName = 'MicrosoftGraph.Oauth.AuthorizationCode'
            AuthCodeCredential = $AuthCodeCredential
            ResultURL = $web.Url.psobject.copy()
            Application = $Application
            AuthCodeBaseURL = $BaseURL
            Response = $Response
            Issued = Get-date
        }

        [void]$form.Close()
        [void]$Web.Dispose()
        [void]$Form.Dispose()
    }
}