Test-M365TenantStatus
This script checks whether one or more domains are on Microsoft 365, and — when checking multiple domains at once — whether they share the same Entra ID tenant or sit on separate tenants entirely. It uses only public DNS records and the unauthenticated OpenID Connect discovery endpoint, so there's no sign-in, no app registration, and no admin permissions needed. Point it at a domain and get an answer in seconds.
Purpose
This kind of quick, no-auth tenant check comes up more often than you'd expect:
- Pre-sales research — confirm a prospect is already on Microsoft 365 before a discovery call, so you can tailor the conversation instead of asking
- M&A due diligence — determine whether acquired or merging companies already share a tenant, which changes the entire integration plan
- Partner discovery — confirm a client's subsidiary or sister company is on the same tenant before scoping a cross-site integration
- Competitor research — check whether a company has migrated to Microsoft 365 from Google Workspace or another platform
How it works
- MX record check — resolves the domain's MX record and looks for the
*.mail.protection.outlook.compattern that confirms Exchange Online - Tenant ID lookup — queries
https://login.microsoftonline.com/{domain}/.well-known/openid-configuration, a public, unauthenticated endpoint, and extracts the tenant GUID from the issuer URL - Tenant comparison — when multiple domains are checked in the same run, matching tenant IDs mean the domains share a single Entra ID tenant; different IDs mean they're on separate tenants
Prerequisites
- None — no Microsoft 365 sign-in, app registration, or admin role required
- PowerShell 5.1+ or PowerShell 7 with the
DnsClientmodule (built in on Windows) - Outbound internet access to DNS and
login.microsoftonline.com
PowerShell Script
# ── M365 Tenant Detection Script ─────────────────────────────
# Checks whether domains are on Microsoft 365 and whether they
# share a tenant or are on separate tenants.
# No authentication required — uses public DNS and OIDC endpoints.
$domains = @(
"contoso.com",
"fabrikam.com"
)
foreach ($domain in $domains) {
Write-Host "`n── $domain ──────────────────────────" -ForegroundColor Cyan
# Step 1 — MX record (confirms Exchange Online presence)
$mx = Resolve-DnsName -Name $domain -Type MX -ErrorAction SilentlyContinue
$onExchangeOnline = $mx | Where-Object { $_.NameExchange -like "*.mail.protection.outlook.com" }
if ($onExchangeOnline) {
Write-Host " MX: Exchange Online confirmed" -ForegroundColor Green
} elseif ($mx) {
Write-Host " MX: $($mx[0].NameExchange) (not Exchange Online)" -ForegroundColor Yellow
} else {
Write-Host " MX: No record found" -ForegroundColor Red
}
# Step 2 — Tenant ID via OpenID Connect discovery endpoint
try {
$oidc = Invoke-RestMethod `
-Uri "https://login.microsoftonline.com/$domain/.well-known/openid-configuration" `
-ErrorAction Stop
$tenantId = ($oidc.issuer -split "/")[3]
Write-Host " Tenant ID: $tenantId" -ForegroundColor Green
Write-Host " Tenant URL: https://login.microsoftonline.com/$tenantId" -ForegroundColor Gray
}
catch {
Write-Host " Tenant ID: Not resolvable — domain not on M365 or not federated" -ForegroundColor Red
}
}
Write-Host "`n── Summary ──────────────────────────────────────" -ForegroundColor Cyan
Write-Host "Matching tenant IDs = shared tenant. Different IDs = separate tenants." -ForegroundColor Gray
Usage Notes
- Add as many domains as you like to the
$domainsarray — the tenant ID comparison becomes useful as soon as you check two or more - A resolvable tenant ID confirms the domain is registered with Entra ID; it does not by itself confirm active Microsoft 365 licensing — cross-check with the MX result for Exchange Online
- A domain can be registered with Entra ID (tenant ID resolves) without using Exchange Online, if mail is hosted elsewhere
- Some domains front their mail through a third-party gateway, which will mask the Exchange Online MX pattern even if the tenant ID still resolves
- This only reads public information — it never touches the target tenant, so it's safe to run against any domain without prior notice or consent