Public/Connect-TenantLens.ps1

function Connect-TenantLens {
    <#
    .SYNOPSIS
        Connects to Microsoft Graph with the read-only scopes TenantLens needs.
    .DESCRIPTION
        Wraps Connect-MgGraph. By default requests the union of all read-only
        scopes required by the shipped collectors. Any scope containing 'Write'
        is refused - TenantLens is read-only by design.
    .EXAMPLE
        Connect-TenantLens
    .EXAMPLE
        Connect-TenantLens -TenantId contoso.onmicrosoft.com -UseDeviceCode
    #>

    [CmdletBinding(DefaultParameterSetName = 'Interactive')]
    param(
        [Parameter(ParameterSetName = 'Interactive')]
        [string]$TenantId,

        # Override the requested scopes (read-only scopes only).
        [Parameter(ParameterSetName = 'Interactive')]
        [string[]]$Scopes,

        [Parameter(ParameterSetName = 'Interactive')]
        [switch]$UseDeviceCode
    )

    if (-not $Scopes -or @($Scopes).Count -eq 0) { $Scopes = Get-TLDefaultScope }

    $writeScopes = @($Scopes | Where-Object { $_ -match '(?i)write' })
    if ($writeScopes.Count -gt 0) {
        throw ("TenantLens is read-only by design and refuses to request write scopes: {0}" -f ($writeScopes -join ', '))
    }

    $connectParams = @{ Scopes = @($Scopes); NoWelcome = $true; ErrorAction = 'Stop' }
    if ($TenantId) { $connectParams['TenantId'] = $TenantId }
    if ($UseDeviceCode) { $connectParams['UseDeviceCode'] = $true }

    Connect-MgGraph @connectParams | Out-Null

    $context = Get-MgContext
    if (-not $context) { throw 'Connect-MgGraph did not establish a Graph context.' }

    [pscustomobject]@{
        TenantId = $context.TenantId
        Account  = $context.Account
        AuthType = $context.AuthType
        Scopes   = @($context.Scopes)
    }
}