Private/Resolve-RaidinessTenant.ps1

<#
    Works out which tenant a run is about, from what the caller gave and what
    the Graph session knows. The optional modules sign in with a tenant id or
    default domain; the SharePoint module additionally needs the tenant *name*
    (the "contoso" in contoso-admin.sharepoint.com), which is derived from a
    <name>.onmicrosoft.com id or, failing that, read from /organization — one
    GET, and a miss is a $null, never an error: the SharePoint module is then
    skipped with a note.
#>

function Resolve-RaidinessTenant {
    [CmdletBinding()]
    [OutputType([pscustomobject])]
    param(
        [string] $TenantId,
        [string] $TenantName
    )

    $ErrorActionPreference = 'Stop'

    $context = Get-MgContext
    if (-not $TenantId) {
        if ($context -and $context.TenantId) {
            $TenantId = $context.TenantId
        }
        else {
            throw 'Pass -TenantId or run Connect-Raidiness first.'
        }
    }

    if (-not $TenantName) {
        if ($TenantId -match '^(?<name>[^.]+)\.onmicrosoft\.com$') {
            $TenantName = $Matches.name
        }
        elseif ($context) {
            try {
                $organization = Invoke-MgGraphRequest -Method GET -Uri '/v1.0/organization' -OutputType PSObject
                $initial = @($organization.value | ForEach-Object { $_.verifiedDomains } | Where-Object { $_.isInitial } | Select-Object -First 1)
                if ($initial.Count -gt 0 -and $initial[0].name -match '^(?<name>[^.]+)\.onmicrosoft\.com$') {
                    $TenantName = $Matches.name
                }
            }
            catch {
                Write-Verbose "Could not read the initial domain from /organization: $($_.Exception.Message)"
            }
        }
    }

    [pscustomobject]@{
        TenantId   = $TenantId
        TenantName = $TenantName ? $TenantName : $null
    }
}