GenerateO365RefreshToken.ps1

<#PSScriptInfo
 
.VERSION 1.0
 
.GUID 9d8dac7e-cee0-4b96-973b-b62f98464d3f
 
.AUTHOR Samraj
 
.COMPANYNAME
 
.COPYRIGHT
 
.TAGS
 
.LICENSEURI
 
.PROJECTURI
 
.ICONURI
 
.EXTERNALMODULEDEPENDENCIES
 
.REQUIREDSCRIPTS
 
.EXTERNALSCRIPTDEPENDENCIES
 
.RELEASENOTES
 
 
.PRIVATEDATA
 
#>


<#
 
.DESCRIPTION
 Exterro eDiscovery platform connect with O365 with the help of refresh token to support modern authentication.
 
#>
 

#-- This script is used for Exterro's eDiscovery Platform.
#-- @author: Samraj K
#-- Code snippets are referred from PS gallery projects.

$ErrorActionPreference = "Stop"
$WelknownClientId = "1b730954-1685-4b74-9bfd-dac224a7b894"
[bool]  $Global:autoClosed=$false;
Function Show-LoginWindow
{
    param(
        [System.Uri]$Url
    )
    Add-Type -AssemblyName System.Web
    Add-Type -AssemblyName System.Windows.Forms
 
    $form = New-Object -TypeName System.Windows.Forms.Form -Property @{Width=500;Height=650}
    $web  = New-Object -TypeName System.Windows.Forms.WebBrowser -Property @{Width=400;Height=600;Url=($url ) }
    $DocComp  = {
        $Global:uri = $web.Url.AbsoluteUri
        if ($Global:Uri -match "error=[^&]*|code=[^&]*") {$Global:autoClosed=$true; $form.Close() }
    }
    $web.ScriptErrorsSuppressed = $true
    $web.Add_DocumentCompleted($DocComp)
    $form.Text="Exterro Token Generation"

    $Icon = [system.drawing.icon]::ExtractAssociatedIcon($PSHOME + "\powershell.exe")
    $form.Icon=$Icon
   # $form.CompanyName="Exterro Inc"
    $form.Controls.Add($web)
    $form.Add_Shown({$form.Activate()})
    $form.ShowDialog() | Out-Null
    $queryOutput = [System.Web.HttpUtility]::ParseQueryString($web.Url.Query)
    
    if($Global:autoClosed){
    $output = @{}
    foreach($key in $queryOutput.Keys){
        $output["$key"] = $queryOutput[$key]
    }
    return $output 
    }else{
    $FileLocation="tempFile.html"
    if (Test-Path $FileLocation) 
    {
      Remove-Item $FileLocation
    }
    $web.DocumentText | Out-File -FilePath $FileLocation -NoClobber
    

  $output=  GetStringBetweenTwoStrings -firstString "code=" -secondString "\\u0026session_state=" -importPath $FileLocation
  
  Remove-Item �path $FileLocation
  return $output 
  }
    
}

function GetStringBetweenTwoStrings($firstString, $secondString, $importPath){

    #Get content from file
    $file = Get-Content $importPath

    #Regex pattern to compare two strings
    $pattern = "$firstString(.*?)$secondString"

    #Perform the opperation
    $result = [regex]::Match($file,$pattern).Groups[1].Value

    #Return result
    return $result

}

function Display {
    param(
        [String]$codes
    )
    [void][Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')

    $title = 'Refresh Token'
    $msg   = 'Refresh token is copied to your clipboard. Paste it in private key field in realm. Manual copy also allowed.'

    $text = [Microsoft.VisualBasic.Interaction]::InputBox($msg, $title, $codes)

}

function Get-ExterroPSO365RefreshToken {
    
    Unblock-File -Path $MyInvocation.ScriptName;

    $refreshToken = ""
    $responseCode=""
        
        $codeData = Show-LoginWindow -Url "https://login.windows.net/common/oauth2/authorize?resource=https://ps.compliance.protection.outlook.com&client_id=$WelknownClientId&response_type=code&redirect_uri=urn:ietf:wg:oauth:2.0:oob&prompt=login" + ";"
       if($Global:autoClosed){
        If ($codeData["error"]) {
            "An error occurred accessing https://ps.compliance.protection.outlook.com : " + $codeData["error"]
            return
        } ElseIf ($codeData["code"]) {
            $responseCode = $codeData["code"] ;
        } Else {
            "No code obtained from the endpoint url." ;
            return
        }
        }else{
        $responseCode = $codeData;
        }

        #Fetch the access token
    
        $postParams = @{grant_type='authorization_code';code=$responseCode;client_id=$WelknownClientId;redirect_uri='urn:ietf:wg:oauth:2.0:oob'}
        $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
        $headers.Add("Content-Type", 'application/x-www-form-urlencoded')
        $response=Invoke-RestMethod -Uri https://login.windows.net/common/oauth2/token -Method POST -Body $postParams -Headers $headers

        Set-Clipboard -Value $response.refresh_token
        #$response | Out-File -FilePath "AccessToken.txt"
        Display $response.refresh_token;

}

Get-ExterroPSO365RefreshToken