Scan coverage
70 checks across your Microsoft 365 tenant
Tenant Hawk scans the Entra organization and M365 workloads MSPs actually review with clients — security, cost, reliability, and hygiene — not Azure ARM resources or ops consoles.
Identity
12 checks- Standard
Conditional Access coverage
security.conditional-access · reads Policy.Read.All
- Standard
Legacy authentication
security.legacy-auth · reads Policy.Read.All
- Standard
MFA registration gaps
security.mfa-registration · reads Reports.Read.All
- Standard
Privileged role assignments
security.admin-roles · reads Directory.Read.All
- Standard
Guest account sprawl
security.guest-accounts · reads User.Read.All
- Standard
Inactive user accounts
hygiene.inactive-users · reads User.Read.All
- Standard
Disabled users outside offboarding groups
hygiene.disabled-outside-group · reads Directory.Read.All, User.Read.All
- Standard
Stale guest accounts
security.stale-guests · reads User.Read.All
- Informational
Guest invitation spike
security.guest-invite-sprawl · reads User.Read.All
- Standard
Users without a manager
hygiene.users-no-manager · reads User.Read.All
- Standard
Privileged users without MFA
security.privileged-user-no-mfa · reads Directory.Read.All, Reports.Read.All
- Standard
Standing privileged role access
security.pim-standing-access · reads RoleManagement.Read.All
Teams
14 checks- Standard
Empty groups
hygiene.empty-groups · reads Directory.Read.All
- Standard
Ownerless groups
hygiene.ownerless-groups · reads Directory.Read.All
- Standard
Ownerless Microsoft Teams
hygiene.ownerless-teams · reads Directory.Read.All
- Standard
Empty Microsoft Teams
hygiene.empty-teams · reads Directory.Read.All
- Standard
Stale Microsoft Teams
hygiene.stale-teams · reads Reports.Read.All
- Standard
Teams with no active channels
hygiene.teams-no-active-channels · reads Reports.Read.All
- Standard
Guest-heavy Teams
hygiene.teams-guest-heavy · reads Reports.Read.All
- Informational
Groups with risky naming patterns
hygiene.groups-naming-chaos · reads Directory.Read.All
- Deep scan
Inactive Teams channels
hygiene.inactive-channels · reads Team.ReadBasic.All, ChannelMessage.Read.All
- Deep scan
Empty Teams channels
hygiene.empty-channels · reads Team.ReadBasic.All, ChannelMessage.Read.All
- Deep scan
Ownerless private channels
hygiene.private-channels-ownerless · reads Team.ReadBasic.All, Channel.ReadBasic.All
- Deep scan
Teams with disabled owners
hygiene.teams-disabled-owner · reads User.Read.All, Team.ReadBasic.All
- Deep scan
Outdated Teams apps
hygiene.teams-outdated-apps · reads Team.ReadBasic.All
- Deep scan
Unverified Teams apps
hygiene.teams-unverified-apps · reads Team.ReadBasic.All
SharePoint
13 checks- Standard
Org-wide SharePoint sharing policy
hygiene.sharing · reads SharePointTenantSettings.Read.All
- Standard
Sites with external sharing
hygiene.sharepoint-external-sites · reads Reports.Read.All
- Standard
Stale SharePoint sites
hygiene.sharepoint-stale-sites · reads Reports.Read.All
- Standard
High-storage SharePoint sites
hygiene.sharepoint-high-storage · reads Reports.Read.All
- Standard
Empty SharePoint sites
hygiene.sharepoint-empty-sites · reads Reports.Read.All
- Standard
Ownerless SharePoint sites
hygiene.sharepoint-ownerless-sites · reads Reports.Read.All
- Standard
Sites with inactive files
hygiene.sharepoint-inactive-files · reads Reports.Read.All
- Deep scan
SharePoint sites with unused pages
hygiene.sharepoint-unused-pages · reads Reports.Read.All
- Deep scan
Stale SharePoint site pages
hygiene.sharepoint-stale-site-pages · reads Reports.Read.All
- Deep scan
SharePoint anonymous links
hygiene.sharepoint-anonymous-links · reads Reports.Read.All
- Deep scan
Stale OneDrive accounts
hygiene.onedrive-stale · reads Reports.Read.All
- Deep scan
High-storage OneDrive accounts
cost.onedrive-high-storage · reads Reports.Read.All
- Deep scan
High-storage stale team sites
cost.stale-team-sites-storage · reads Reports.Read.All
Exchange
9 checks- Standard
External mailbox forwarding
hygiene.mailbox-forwarding-external · reads Mail.ReadBasic.All, User.Read.All
- Standard
Mailbox forwarding enabled
hygiene.mailbox-forwarding-enabled · reads Mail.ReadBasic.All, User.Read.All
- Standard
Inactive mailboxes
hygiene.inactive-mailboxes · reads Reports.Read.All
- Standard
High-storage mailboxes
hygiene.mailbox-high-storage · reads Reports.Read.All
- Standard
Licensed inactive mailboxes
cost.inactive-mailbox-licenses · reads Reports.Read.All, User.Read.All, Organization.Read.All
- Deep scan
Shared mailboxes without delegates
hygiene.shared-mailbox-no-delegate · reads Reports.Read.All
- Deep scan
Inactive shared mailboxes
hygiene.shared-mailbox-inactive · reads Reports.Read.All
- Deep scan
Stale mailbox auto-replies
hygiene.mailbox-auto-reply-stale · reads Mail.ReadBasic.All
- Deep scan
Unused resource mailboxes
hygiene.resource-mailbox-unused · reads Reports.Read.All
Devices
6 checks- Standard
Stale Intune device sync
reliability.intune-stale-sync · reads DeviceManagementManagedDevices.Read.All
- Standard
Non-compliant Intune devices
hygiene.intune-noncompliant · reads DeviceManagementManagedDevices.Read.All
- Standard
Entra devices not in Intune
hygiene.entra-unmanaged-devices · reads Device.Read.All, DeviceManagementManagedDevices.Read.All
- Standard
Intune enrollments without Entra device
hygiene.intune-ghost-enrollment · reads Device.Read.All, DeviceManagementManagedDevices.Read.All
- Standard
Stale Entra device sign-ins
reliability.entra-stale-devices · reads Device.Read.All
- Standard
Personally owned Intune enrollments
hygiene.personal-device-enrolled · reads DeviceManagementManagedDevices.Read.All
Apps
8 checks- Standard
Expiring app secrets and certs
reliability.expiring-secrets · reads Application.Read.All
- Standard
Expiring enterprise app secrets
reliability.service-principal-secrets · reads Application.Read.All
- Standard
Over-permissioned enterprise apps
security.over-permissioned-apps · reads Application.Read.All, Directory.Read.All
- Standard
Unused enterprise apps
hygiene.unused-enterprise-apps · reads Application.Read.All, AuditLog.Read.All
- Standard
Ownerless app registrations
hygiene.app-without-owners · reads Application.Read.All
- Standard
Ownerless enterprise apps
hygiene.enterprise-app-no-owners · reads Application.Read.All
- Standard
Apps with Global Administrator role
security.app-global-admin-role · reads Directory.Read.All
- Standard
Multi-tenant apps with credentials
hygiene.multi-tenant-apps · reads Application.Read.All
Copilot
8 checks- Standard
Unused Copilot license seats
cost.unused-copilot-licenses · reads Organization.Read.All
- Standard
Licensed inactive Copilot users
cost.copilot-licensed-inactive · reads Reports.Read.All, User.Read.All, Organization.Read.All
- Standard
Copilot on disabled accounts
cost.copilot-assigned-disabled-user · reads User.Read.All, Organization.Read.All
- Standard
Low Copilot adoption
hygiene.copilot-low-adoption · reads Reports.Read.All, User.Read.All, Organization.Read.All
- Standard
Copilot Chat-only users
hygiene.copilot-app-skew · reads Reports.Read.All
- Standard
Copilot users without MFA
security.copilot-licensed-no-mfa · reads User.Read.All, Organization.Read.All, Reports.Read.All
- Standard
Copilot readiness blockers
copilot.readiness-blockers · reads
- Informational
Copilot Chat-only usage pattern
hygiene.copilot-chat-only-usage · reads Reports.Read.All
Cost
3 checks- Standard
Licenses on disabled accounts
cost.disabled-user-licenses · reads User.Read.All, Organization.Read.All
- Standard
Unused license seats
cost.unused-licenses · reads Organization.Read.All
- Standard
Subscription status warnings
cost.license-expiry · reads Organization.Read.All
How findings are scored — and where to be skeptical
70 automated checks, severity-weighted, scored out of 100. Each category starts at 100. Security, reliability, and hygiene lower by finding severity (high 18, medium 7, low 3). Cost also weighs estimated recoverable spend so low license waste earns a better grade. Your overall score is the average across all four categories.
Every check reads from a documented Graph source — the scope is listed next to each check above, and the security page explains what each permission grants. A finding is a starting point for an operator, not a remediation order. Two examples of nuance we bake in rather than hide:
- Inactive users: mobile-only users can look dead on last interactive sign-in while Teams and Outlook keep hitting non-interactive sign-ins in the background, so we consider both. Even then, we do not recommend reclaiming a license on inactivity alone — check leave status and get manager sign-off first, or you will hear from someone on parental leave.
- Licenses on disabled accounts: flagged as its own pass rather than lumped into offboarding exports, because the account disabled weeks ago with an E5 still attached is the one that slips through ticket-driven processes. Some orgs park licenses on disabled accounts intentionally during legal hold — verify before you reclaim.
Deep-scan checks (Teams and SharePoint activity) sample large tenants rather than exhaustively enumerating, and say so in the finding. Usage-report-based checks inherit Microsoft's own reporting lag of up to 48 hours.
Explicitly not included
We scope Tenant Hawk to client-ready M365 tenant reviews. These areas are backlog or out of product scope:
- Azure subscription resources (VMs, storage accounts, NSGs)
- Microsoft Defender for Endpoint deep posture
- Power Platform (Flows, environments, connectors)
- Purview / Copilot DLP label coverage
- Undocumented Microsoft admin-center internal APIs
Need a specific workload? Browse feature pages or start a scan to see what your tenant exposes today.
See your tenant's coverage in minutes
Connect read-only, run a scan, and get sector-filtered findings with dollar impact where it matters.
Start free scan