Every shared mailbox in Microsoft 365 sits on top of a real Entra ID user account, and when that account is left enabled it becomes a password-only identity that nobody owns, nobody watches and nobody notices being used. This guide is one task done end to end: list every shared, room, equipment and service-style mailbox in an Exchange Online tenant, join each one to its Entra ID account, find the ones that can still sign in, check whether anyone actually has, and block them safely with a rollback. It is written for Microsoft 365 administrators, identity engineers and SOC analysts. Commands come from Microsoft Learn documentation; the governance case for shared accounts in general is in the Shared and Generic Accounts Governance Guide, and this page is the audit procedure.
Key takeaways
Microsoft's rule is unambiguous: its shared mailbox documentation says a shared mailbox is not intended for direct sign-in, that the account has a system-generated password nobody should know, and that sign-in for the account should always be blocked and kept blocked.
The mailbox and the account are two objects: Exchange Online tells you which mailboxes are shared (RecipientTypeDetails), Entra ID tells you whether the account can sign in (accountEnabled); the join key is the mailbox's ExternalDirectoryObjectId.
Not every non-person mailbox should be blocked: a Teams Rooms resource account signs in from the device and needs a password, and a scanner or application mailbox may authenticate by design. Those become documented service identities with an owner, not silent exceptions.
Use the right sign-in field:lastSignInDateTime records attempts, including failures; lastSuccessfulSignInDateTime is the one that shows the account was actually used.
Block, then watch: disabling the account does not remove delegated access through Full Access or Send As, so users keep working; a successful sign-in by a blocked shared mailbox afterwards is a high-confidence alert.
When you need this
Baseline hygiene: the CIS Microsoft 365 Foundations Benchmark carries a Level 1 recommendation (1.2.2) to ensure sign-in to shared mailboxes is blocked. If you are measured against the benchmark, this is the evidence.
After converting leavers' mailboxes: converting a user mailbox with Set-Mailbox -Identity <MailboxIdentity> -Type Shared changes the mailbox type; Microsoft's conversion page says nothing about the Entra ID account, so treat the account as still enabled, with the leaver's password, until you have checked.
During a compromise investigation: an enabled shared mailbox account is a valid cloud account (ATT&CK T1078.004) that is rarely covered by MFA registration; check it alongside the accounts in the Microsoft 365 Tenant Compromise Playbook.
Exchange Online PowerShell with a role that can run Get-EXOMailbox, Get-EXOMailboxPermission and Get-RecipientPermission
Microsoft Learn cmdlet reference
Account state
Microsoft Graph PowerShell with User.Read.All to read accountEnabled, assignedLicenses, onPremisesSyncEnabled, passwordPolicies and lastPasswordChangeDateTime (all need $select or -Property)
Graph user resource
Sign-in evidence
AuditLog.Read.All and a Microsoft Entra ID P1 or P2 licence for signInActivity; Reports Reader at least to view sign-in logs in the admin centre
Graph user resource; Entra sign-in logs overview
Change permission
User.EnableDisableAccount.All plus User.Read.All is the least privileged Graph combination for changing accountEnabled; the caller also needs a sufficiently privileged admin role because the property is a sensitive action
Graph update user
Change record
Pre-approved change for "block sign-in on non-person mailboxes", with a named exception list
Internal
Treat the audit script as a non-human identity: if you run the sweep unattended through an app registration, grant read scopes only, keep the write scope on a separate, interactively approved path, and record the app in your service account inventory. See the Service Account Security Guide.
Know your source of authority: accounts with onPremisesSyncEnabled true come from Active Directory through sync. Microsoft's update-user page notes that which properties you can change for synced users depends on the source of authority, so plan to disable those accounts in on-premises AD rather than in the cloud.
Step-by-step
Steps 1 to 5 are read-only. Step 6 changes the tenant.
List every non-person mailbox. Run Get-EXOMailbox -RecipientTypeDetails SharedMailbox,RoomMailbox,EquipmentMailbox,SchedulingMailbox -ResultSize unlimited. The default result size is 1,000, so a tenant-wide audit without -ResultSize unlimited is silently truncated. Add -Properties for ExternalDirectoryObjectId, PrimarySmtpAddress and WhenCreated so each row carries its Entra ID object ID.
Find service mailboxes that are typed as user mailboxes. Scanners, ticketing systems, line-of-business applications and old "noreply@" senders are often ordinary UserMailbox objects with a licence. These do not appear in step 1. Pull UserMailbox recipients and flag likely service mailboxes by naming convention (noreply, scan, alerts, svc), by a missing manager or department in Entra ID, and by SMTP AUTH being enabled: Get-CASMailbox -ResultSize unlimited and inspect SmtpClientAuthenticationDisabled (False means enabled for that mailbox, blank means it inherits the organisation setting).
Join each mailbox to its account. For every ExternalDirectoryObjectId, read the account with Graph, for example Get-MgUser -UserId <id> -Property "displayName,userPrincipalName,accountEnabled,assignedLicenses,onPremisesSyncEnabled,passwordPolicies,lastPasswordChangeDateTime,signInActivity". Keep one row per mailbox with type, account state and licence. Any row with accountEnabled true is in scope for the rest of the procedure.
Check whether the account has actually been used. From signInActivity record lastSuccessfulSignInDateTime, lastSignInDateTime and lastNonInteractiveSignInDateTime. Microsoft documents that the last two include unsuccessful attempts, so a recent value there with no successful sign-in means someone is trying the account, which is itself a finding. lastSuccessfulSignInDateTime has only existed since 1 December 2023 and is not backfilled. For accounts with any recent success, pull the detail from the sign-in logs (interactive and non-interactive) with Get-MgAuditLogSignIn filtered on the user ID, and note application, client, IP and Conditional Access result.
Record who already has delegated access. Run Get-EXOMailboxPermission for Full Access and Get-RecipientPermission for Send As on every in-scope mailbox. If the people who sign in directly already hold delegated rights, blocking sign-in costs them nothing. If they do not, grant the permission before you block, so the change does not become an outage.
Classify and act. Use the decision table below. For mailboxes that should not sign in, block the account with Graph: Update-MgUser -UserId <UPN> -BodyParameter @{ accountEnabled = $false }, the pattern Microsoft documents for blocking accounts (bulk: one UPN per line in a file, piped to the same command). For synced accounts, disable the object in AD and let sync carry it. Run a pilot of ten or so low-traffic shared mailboxes first and wait one business day before the remainder.
Tidy what blocking does not fix. Remove licences that were only there because people signed in directly, where Microsoft's licensing rules allow it (an unlicensed shared mailbox holds up to 50 GB; archive, litigation hold and 100 GB need Exchange Online Plan 2 or Plan 1 with the Exchange Online Archiving add-on). Disable SMTP AUTH per mailbox where no device uses it with Set-CASMailbox -Identity <mailbox> -SmtpClientAuthenticationDisabled $true.
Decision table
Finding
Typical cause
Action
Shared mailbox, enabled, no successful sign-in on record
Team shares the password, or a converted leaver mailbox still used with the leaver's password
Grant Full Access and Send As to named users, then block; reset the password; check the sign-ins for unfamiliar IPs and applications
Shared mailbox, enabled, failed attempts only
Password spraying or a stale device
Block now; investigate the source IPs
Room resource account used by a Teams Rooms device
Required by design: Microsoft says the device uses the resource account to sign in, and that password never expires is a requirement for shared Teams devices
Keep enabled; register as a service identity with owner; restrict with Conditional Access for Teams devices; confirm the Teams Rooms licence
Room or equipment mailbox with no device
Booking only
Block sign-in
Service mailbox (scanner, app, alerts) with SMTP AUTH or app sign-in
Re-run steps 1 and 3: the count of shared, room and equipment mailbox accounts with accountEnabled true should equal the size of the approved exception list, and every exception should have an owner.
Spot-check one account:Get-MgUser -UserId <UPN> -Property "displayName,accountEnabled" | Select displayName, accountEnabled should return false.
Confirm delegates still work: a user with Full Access opens the mailbox in Outlook on the web; a user with Send As sends a test message. Microsoft notes access through membership works in Outlook on the web and the Outlook mobile apps.
Watch the logs for a week: failed sign-ins for blocked accounts show who was still using the password; contact them rather than re-enabling.
Measures that show the control is working
Measure
How to calculate
Target
Enabled shared mailbox accounts
Shared mailboxes whose account has accountEnabled true
0
Undocumented enabled resource or service mailboxes
Enabled accounts in steps 1 and 2 not on the exception register
0
Successful sign-ins by blocked mailbox accounts
Sign-in log events with success for any account on the blocked list
0; each one is an incident
Converted mailboxes checked
Conversions in the period whose account was blocked within 1 business day
100%
Exceptions with owner and review date
Exception rows with both fields set
100%
Rollback and common errors
Rollback: keep the CSV from step 3. To restore one account, use the unblock pattern Microsoft documents, Update-MgUser -UserId <UPN> -BodyParameter @{ accountEnabled = $true }; for synced objects re-enable in AD. Re-enable only with a ticket and a date by which delegated access replaces direct sign-in.
Insufficient privileges on update:accountEnabled is subject to sensitive action restrictions, so a role that can edit other user properties may still be refused. Use a role that Microsoft lists for the action rather than broadening an app's permissions.
Change reverts on its own: the object is synced from AD; the cloud value is not authoritative.
Only 1,000 rows:-ResultSize unlimited was missed on Get-EXOMailbox or Get-CASMailbox.
No signInActivity returned: the tenant lacks Entra ID P1 or P2, the caller lacks AuditLog.Read.All, or the account never signed in (or last did before April 2020). Absence is not proof of no use; fall back to the sign-in logs for the retention you have.
Teams Rooms device signs out: a room resource account used by a device was blocked, or its password expired. Re-enable, set DisablePasswordExpiration as Microsoft requires for these accounts, and add it to the exception register.
Hardening afterwards
Make blocking part of creation and conversion: add "block sign-in on the account" as a step in the shared mailbox creation runbook and the leaver mailbox conversion runbook, and check it in the Employee Offboarding Security Checklist.
Alert on use: send Entra sign-in logs to your SIEM and alert on any successful interactive or non-interactive sign-in by an account on the blocked list, and on any change of accountEnabled to true for those accounts.
Constrain the exceptions: Conditional Access policies scoped to the exception accounts (named locations, compliant device, specific client apps). Microsoft notes that Teams shared devices do not support security defaults and are controlled through Conditional Access.
Review delegation too: blocking sign-in moves risk to Full Access and Send As holders. Review them on the cycle in the Mailbox Delegation Review Checklist; attackers who gain delegate rights are using ATT&CK T1098.002 Additional Email Delegate Permissions.
Schedule the sweep: run steps 1 to 4 monthly (our recommendation) and keep each export as audit evidence.
Common failure patterns
Auditing only SharedMailbox: room, equipment and licensed service mailboxes are skipped, and those are where enabled, password-only accounts tend to live.
Converting a leaver's mailbox and stopping there: the mailbox becomes shared but the account, password and any registered methods are untouched.
Reading lastSignInDateTime as proof of use: it counts failed attempts, so it overstates use and can hide that the account is under attack rather than in service.
Blanket MFA exclusion for "shared accounts": excluding the whole class from Conditional Access leaves every enabled one protected by a password alone. Forgotten, password-only accounts are exactly how the Microsoft Midnight Blizzard Breach began: a legacy test account without MFA was password-sprayed.
Blocking without granting delegation first: the team loses access, the change is rolled back, and the mailbox stays enabled for another year.
Exceptions with no owner: the scanner mailbox kept for SMTP AUTH outlives the scanner, and nobody can say whether its sign-ins are expected.
NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 11 November 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security.
nhimg.org
Free weekly newsletter
Subscribe to the NHI & AI Identity Journal
The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.