functions/azure/Connect-ToAzure.ps1

function Connect-ToAzure {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $false)]
        [string]$TenantId,

        [Parameter(Mandatory = $false)]
        [string]$SubscriptionId,

        [Parameter(Mandatory = $false)]
        [string]$ClientId,

        [Parameter(Mandatory = $false)]
        [object]$ClientSecret,

        [Parameter(Mandatory = $false)]
        [string]$Scope = 'https://management.azure.com/.default',

        [Parameter(Mandatory = $false)]
        [string]$ApiVersion = $BcAdminSession.AzureRestApiVersion,

        [Parameter(Mandatory = $false)]
        [switch]$Force
    )

    # TODO support refresh_token flow
    if ($null -ne $BcAdminSession.AzureAccessTokenValidTo)
    {
        if (($BcAdminSession.AzureAccessTokenValidTo -gt (Get-Date).AddSeconds(60)) -and -not $Force)
        {
            return $true
        } else {
            Write-Warning "access_token will be invalid in less than 60 seconds!"

            if (([string]::IsNullOrWhiteSpace($ClientId))) {
                $ClientId = $BcAdminSession.AzureClientId
            }
            if ($ClientSecret -is [SecureString]) {
                if (([string]::IsNullOrWhiteSpace($ClientSecret))) {
                    $ClientSecret = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($BcAdminSession.AzureClientSecret))
                }
            } elseif(-not ($ClientSecret -is [string])) {
                Write-Error "ClientSecret has to be of type [SecureString] or [String]!"
                return $false
            }
            if (([string]::IsNullOrWhiteSpace($Scope))) {
                $Scope = $BcAdminSession.AzureAuthenticationScope
            }
            if (([string]::IsNullOrWhiteSpace($TenantId))) {
                $TenantId = $BcAdminSession.AzureTenantId
            }
            if (([string]::IsNullOrWhiteSpace($SubscriptionId))) {
                $SubscriptionId = $BcAdminSession.AzureSubscriptionId
            }
        }
    }

    if ($ClientSecret -is [SecureString]) {
        [string]$ClientSecret = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($ClientSecret))
    }

    if (([string]::IsNullOrWhiteSpace($ClientId)) -or ([string]::IsNullOrWhiteSpace($ClientSecret)) -or ([string]::IsNullOrWhiteSpace($Scope))) {
        Write-Error "Unable to connect to Microsoft Azure! ClientId: $ClientId, ClientSecret: $(-not ([string]::IsNullOrWhiteSpace($ClientSecret))), Scope: $Scope"
    }
    
    $body = @{
        grant_type    = "client_credentials"
        client_id     = $ClientId
        client_secret = $ClientSecret
        scope         = $Scope
    }

    $requestTime = Get-Date
    $tokenResponse = Invoke-RestMethod -Method Post -Uri "https://login.microsoftonline.com/$TenantId/oauth2/v2.0/token" -Body $body -ContentType "application/x-www-form-urlencoded"

    if ($tokenResponse)
    {
        if (-not ([string]::IsNullOrWhiteSpace($ApiVersion))) {
            $BcAdminSession.AzureRestApiVersion = $ApiVersion
        }
        $BcAdminSession.AzureAuthenticationScope = $Scope
        $BcAdminSession.AzureTenantId = $TenantId
        $BcAdminSession.AzureSubscriptionId = $SubscriptionId
        $BcAdminSession.AzureClientId = $ClientId
        $BcAdminSession.AzureClientSecret = ConvertTo-SecureString $ClientSecret -AsPlainText -Force
        $BcAdminSession.AzureAccessTokenType = $tokenResponse.token_type
        $BcAdminSession.AzureAccessToken = $tokenResponse.access_token
        $BcAdminSession.AzureAccessTokenValidFrom = $requestTime
        $BcAdminSession.AzureAccessTokenValidTo = $requestTime.AddSeconds($tokenResponse.expires_in)
        $BcAdminSession.AzureRequestHeaderAuthorization = "$($tokenResponse.token_type) $($tokenResponse.access_token)"
        return $true
    } else {
        Write-Warning "Microsoft Azure Authentifizierung fehlgeschlagen!"
        return $false
    }
}