Functions/Connect-GSuiteAdminAccount.ps1
<#
.SYNOPSIS This function uses permanent refresh tokens of various scopes stored in an endpoint to get temporary GSuite access tokens. #> function Connect-GSuiteAdminAccount { [CmdletBinding(PositionalBinding=$false, DefaultParameterSetName = 'AllScopes')] [OutputType([Bool])] param ( # The MSPComplete endpoint containing the application ID and client secret in the credential. [Parameter(Mandatory=$true, ValueFromPipeline=$true)] [ValidateNotNull()] $endpoint, # Whether to retrieve access tokens using all available refresh tokens [Parameter(Mandatory=$false, ParameterSetName="AllScopes")] [ValidateNotNull()] [Switch]$allScopes, # Whether to retrieve access token of the scope 'https://www.googleapis.com/auth/admin.directory.user' [Parameter(Mandatory=$false, ParameterSetName="IndividualScope")] [ValidateNotNull()] [Switch]$user, # Whether to retrieve access token of the scope 'https://www.googleapis.com/auth/admin.directory.group' [Parameter(Mandatory=$false, ParameterSetName="IndividualScope")] [ValidateNotNull()] [Switch]$group, # Whether to retrieve access token of the scope 'https://www.googleapis.com/auth/admin.directory.orgunit' [Parameter(Mandatory=$false, ParameterSetName="IndividualScope")] [ValidateNotNull()] [Switch]$organizationalUnit, # Whether to retrieve access token of the scope 'https://www.googleapis.com/auth/admin.directory.userschema' [Parameter(Mandatory=$false, ParameterSetName="IndividualScope")] [ValidateNotNull()] [Switch]$useSchema, # Whether to retrieve access token of the scope 'https://www.googleapis.com/auth/admin.directory.device.mobile' [Parameter(Mandatory=$false, ParameterSetName="IndividualScope")] [ValidateNotNull()] [Switch]$mobileDevice, # Whether to retrieve access token of the scope 'https://www.googleapis.com/auth/admin.directory.user.security' [Parameter(Mandatory=$false, ParameterSetName="IndividualScope")] [ValidateNotNull()] [Switch]$security, # Whether to retrieve access token of the scope 'https://www.googleapis.com/auth/admin.directory.customer' [Parameter(Mandatory=$false, ParameterSetName="IndividualScope")] [ValidateNotNull()] [Switch]$customer, # Whether to retrieve access token of the scope 'https://www.googleapis.com/auth/admin.directory.domain' [Parameter(Mandatory=$false, ParameterSetName="IndividualScope")] [ValidateNotNull()] [Switch]$domain, # Select the stream where the messages will be directed. [Parameter(Mandatory=$false)] [ValidateSet("Information", "Warning", "Error", "None")] [String]$outputStream = "Error" ) # If no individual scope is specified, retrieve access tokens for all the scopes if ($PSCmdlet.ParameterSetName -eq "AllScopes") { $allScopes = [Switch]::Present } # Extract all the refresh tokens as well as the application ID and client secret from the endpoint $refreshTokensHashTable = ConvertFrom-GSuiteEndpoint -Endpoint $endpoint $applicationId = $refreshTokensHashTable.ApplicationId $clientSecret = $refreshTokensHashTable.ClientSecret # Initialize the access token hash table $Global:GSuiteAccessTokensHashTable = @{ } # Exchange refresh tokens for access tokens foreach ($refreshToken in $refreshTokensHashTable.GetEnumerator()) { # Skip the client secret and application ID if ($refreshToken.Name -eq "ClientSecret" -or $refreshToken.Name -eq "ApplicationID") { continue } # Skip the scope if the corresponding switch is not present if (!$allScopes -and !(Invoke-Expression "`$$($refreshToken.Name)")) { continue } # Validate that the refresh token exists if ([String]::IsNullOrWhiteSpace($refreshToken.Value)) { Write-OutputMessage "The refresh token of the scope '$($refreshToken.Name)' cannot be found in the endpoint." -OutputStream $outputStream -ReturnMessage:$false return $false } # Construct the REST call $invokeRestMethodParams = @{ Uri = "https://www.googleapis.com/oauth2/v4/token" Method = "POST" Headers = @{ "Content-Type" = "application/json" } Body = @{ client_id = $applicationId client_secret = $clientSecret grant_type = "refresh_token" refresh_token = $refreshToken.Value } | ConvertTo-Json } # Invoke the REST call Write-Information "Retrieving the GSuite access token using the refresh token of the scope '$($refreshToken.Name)'." try { $response = Invoke-RestMethod @invokeRestMethodParams } catch { Write-OutputMessage "Exception occurred while retrieving the GSuite access token of the scope '$($refreshToken.Name)'.`r`n$($_.Exception.Message)" -OutputStream $outputStream -ReturnMessage:$false return $false } # Verify the response if ($null -eq $response -or $response.expires_in -le 0 -or [String]::IsNullOrWhiteSpace($response.access_token)) { Write-OutputMessage "Failed to retrieve the GSuite access token of the scope '$($refreshToken.Name)'." -OutputStream $outputStream -ReturnMessage:$false return $false } # Update the hash table $Global:GSuiteAccessTokensHashTable.Add($refreshToken.Name, $response.access_token) } # Return true if all the access tokens are successfully retrieved return $true } |