GenerateO365RefreshToken.ps1
<#PSScriptInfo
.VERSION 1.1 .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" $PSEndPointUrl = "https://ps.compliance.protection.outlook.com" $O365LoginUrl = "https://login.microsoftonline.com" [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 = 'Please copy the refresh token from the window.' $text = [Microsoft.VisualBasic.Interaction]::InputBox($msg, $title, $codes) } function Get-ExterroPSO365RefreshToken { Unblock-File -Path $MyInvocation.ScriptName; #--- Get the options section Show-Menu �Title 'My Menu' $selection = Read-Host "Please make a selection ( Default : Microsoft global environment)" switch ($selection) { '1' { $PSEndPointUrl = "https://ps.compliance.protection.outlook.com" $O365LoginUrl = "https://login.microsoftonline.com" 'You chose option #1 - Microsoft global environment' } '2' { $PSEndPointUrl = "https://ps.compliance.protection.office365.us" $O365LoginUrl = "https://login.microsoftonline.us" 'You chose option #2 - Microsoft Cloud for US Government (GCC High)' } '3' { $PSEndPointUrl = "https://l5.ps.compliance.protection.office365.us" $O365LoginUrl = "https://login.microsoftonline.us" 'You chose option #3 - Microsoft Cloud for US Government (DoD)' } '4' { $PSEndPointUrl = "https://ps.compliance.protection.outlook.de" $O365LoginUrl = "https://login.microsoftonline.de" 'You chose option #4 - Microsoft Cloud Germany' } '5' { $PSEndPointUrl = "https://ps.protection.outlook.cn" $O365LoginUrl = "https://login.partner.microsoftonline.cn" 'You chose option #5 - Azure and Microsoft 365 operated by 21Vianet in China' } 'q' { return } default { $PSEndPointUrl = "https://ps.compliance.protection.outlook.com" $O365LoginUrl = "https://login.microsoftonline.com" 'Default value - Microsoft global environment' } } #--- End of option section $refreshToken = "" $responseCode="" $codeData = Show-LoginWindow -Url "$O365LoginUrl/common/oauth2/authorize?resource=$PSEndPointUrl&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 $PSEndPointUrl : " + $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 if ($responseCode) { $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 "$O365LoginUrl/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; }else{ Write-Host "Powershell window might be closed abruptly." } } function Show-Menu { param ( [string]$Title = 'M365 Environment Details' ) Clear-Host Write-Host "================ $Title ================" Write-Host "1: Press '1' for Microsoft global environment." Write-Host "2: Press '2' for Microsoft Cloud for US Government(GCC High)." Write-Host "2: Press '3' for Microsoft Cloud for US Government(DoD)." Write-Host "3: Press '4' for Microsoft Cloud Germany." Write-Host "4: Press '5' for Azure and Microsoft 365 operated by 21Vianet in China." Write-Host "Q: Press 'Q' to quit." } Get-ExterroPSO365RefreshToken |