Public/Get-NSPEntraPairingInventory.ps1

function Get-NSPEntraPairingInventory {
    <#
    .SYNOPSIS
        Reads the cloud users of one confirmed tenant, plus AD users, for pairing. Read-only.
    .DESCRIPTION
        Uses the active Graph session, and stops before reading any user if that session's tenant is
        not -ExpectedTenantId. A failed page or directory read throws: a partial inventory would
        turn into false "not found" results, so nothing partial is returned.
 
        AD users come from Get-NSPADUser -All against -Server (add -Forest for every domain in the
        forest), or from -ADUser if you have already read them.
 
        The result holds PII and topology. Keep it in memory or in ignored local state, never in Git
        or Coordination.
    .EXAMPLE
        Connect-NSPEntraPairingGraph -TenantId $tenantId
        $inventory = Get-NSPEntraPairingInventory -ExpectedTenantId $tenantId -Server 'dc01.contoso.example' -Forest
    #>

    [CmdletBinding(DefaultParameterSetName = 'Server')]
    param(
        [Parameter(Mandatory)][guid]$ExpectedTenantId,
        [Parameter(Mandatory, ParameterSetName = 'Server')][ValidateNotNullOrEmpty()][string]$Server,
        [Parameter(ParameterSetName = 'Server')][switch]$Forest,
        [Parameter(Mandatory, ParameterSetName = 'Supplied')][AllowEmptyCollection()][object[]]$ADUser,
        [switch]$ReadRoles,
        [switch]$AssumeNoRoleEligibility
    )

    Import-NSPM365Graph
    $tenantId = Assert-NSPEntraPairingTenant -ExpectedTenantId $ExpectedTenantId

    if ($PSCmdlet.ParameterSetName -eq 'Server') {
        Import-NSPToolkitModule -Name 'NSP.ActiveDirectory'
        if (-not (Get-Command Get-NSPADUser -ErrorAction SilentlyContinue)) { throw 'This NSP.ActiveDirectory has no Get-NSPADUser. Update it.' }
        $read = @{ All = $true; Server = $Server }
        if ($Forest) { $read.Forest = $true }
        $ADUser = @(Read-NSPEntraPairingADPasswordTime -User @(Get-NSPADUser @read))
    }

    $select = 'id,displayName,givenName,surname,userPrincipalName,mail,proxyAddresses,onPremisesImmutableId,onPremisesSyncEnabled,accountEnabled,userType,lastPasswordChangeDateTime'
    $cloudUsers = @(Invoke-NSPGraphCollection -Uri "users?`$select=$select&`$top=999")

    $roles = $null
    if ($ReadRoles) { $roles = Get-NSPEntraPairingRoleState -AssumeNoRoleEligibility:$AssumeNoRoleEligibility }
    [pscustomobject]@{
        ForestWide = [bool]$Forest
        RoleState = $roles
        PSTypeName = 'NSP.M365.UserPairing.Inventory'
        TenantId = $tenantId
        Domains = @($ADUser | ForEach-Object { $_.DomainDNSRoot } | Sort-Object -Unique)
        CloudUsers = $cloudUsers
        ADUsers = @($ADUser)
        CollectedAtUtc = [datetime]::UtcNow.ToString('o')
    }
}