π π§βπΌOS - Calendar External Sharing
Take the calendar-to-the-outside-world URL off the menu, and keep the legitimate scenarios on a governed path.
What this policy is about π β
Every tenant ships with a Default Sharing Policy that lets any user share their calendar with anyone on the internet. The user picks a name, Outlook sends a URL, and whoever holds that URL sees the calendar. No account, no sign-in, no ticket, no trace in your reporting.
This page switches that off at the tenant level and keeps the two scenarios that are actually legitimate, partner free/busy and public booking pages, on paths you control.
A calendar is an org chart with timestamps. It shows who talks to whom, what the projects are called, when the finance lead is in back-to-backs, and which Friday the whole management team is off site. Attackers do their homework before they send the first mail, and a shared calendar does the homework for them.
Why this matters π΅οΈβ
Think about what one shared calendar leaks, assuming nothing worse than the default detail level:
- Relationships. Recurring meetings map the org: who reports to whom, which supplier is in weekly, which lawyer showed up three times this month. πΈοΈ
- Timing. "CFO out of office, Thursday to Monday" is the opening line of a payment-fraud mail. So is "Acquisition sync, 14:00". Invoice fraud is a calendar-reading crime long before it is an email crime. πΈ
- Vocabulary. Subjects and locations hand over project names, customer names, system names. That is the raw material for a phishing mail that sounds like it came from inside the building. π£
- A URL with no lock on it. The link is the credential. Forwarded once, pasted into a group chat, or left in a browser history, and it keeps working. Nobody gets notified, and there is no access log to check afterwards. π
And here is the part that makes it an easy call: hardly anyone uses it. Free/busy lookup with partners runs over organization relationships. Meeting times with outsiders get sorted with a scheduling poll. Public availability lives on a Bookings page. The share-my-calendar-with-a-stranger button mostly sits there, doing nothing, until the day it does something.
π οΈ Configurationβ
Two doors, same room. The admin center checkbox and the Exchange Online sharing policy are the same setting with different paint. Set it in either place, then verify in PowerShell, because the admin center pane is the one that quietly reappears as enabled after a tenant migration or a helpful vendor "fixing Outlook."
Microsoft 365 admin centerβ
Where: Microsoft 365 admin center β Settings β Org settings β Services tab β Calendar.
Role: Exchange Administrator is enough. Global Administrator is not required, so do not use one.
| Setting | Value | Why |
|---|---|---|
| Let your users share their calendars with people outside of your organization who have Office 365 or Exchange | Unchecked | The parent switch. Unchecking it removes external calendar sharing for every mailbox that uses the default policy. |
| Allow anyone to access calendars with an email invitation | Unavailable once the parent is off | This is the anonymous-URL variant, the one where the recipient does not need an account of any kind. It only exists while the parent is on, which is a decent hint about how Microsoft ranks the risk. |
| Calendar detail level | Not applicable | Only relevant if you keep sharing on. See the exception path below. |
Click Save. The change is tenant-wide and takes effect on the next Outlook sync, which in practice means minutes.
Exchange Online PowerShellβ
The same setting, in the place where you can actually prove what it is set to:
Connect-ExchangeOnline
# What is out there right now
Get-SharingPolicy | Format-List Name, Default, Enabled, Domains
# Switch it off
Set-SharingPolicy -Identity "Default Sharing Policy" -Enabled $false
Read the Domains values before you flip anything. They tell you exactly what the tenant has been allowing:
| Domains entry | What it means |
|---|---|
*:CalendarSharingFreeBusySimple | Any external domain, free/busy times only. |
*:CalendarSharingFreeBusyDetail | Any external domain, plus subject and location. This is the one that leaks vocabulary. |
Anonymous:CalendarSharingFreeBusyReviewer | Anyone with the URL, full appointment detail. If you find this, do not just disable the policy, go hunting for what is already published. |
*:ContactsSharing | Contacts, not calendars, riding along in the same policy. Worth knowing before someone reports that contact sharing "broke." |
Clean up what is already shared π§Ήβ
Disabling the policy stops new external sharing and cuts off the mailboxes that use it. It does not tell you what went out the door last year, and that inventory is the part everyone skips.
# Find calendars that are actively published
Get-Mailbox -ResultSize Unlimited | ForEach-Object {
$folder = (Get-MailboxFolderStatistics -Identity $_.PrimarySmtpAddress -FolderScope Calendar |
Where-Object { $_.FolderType -eq 'Calendar' }).Name
Get-MailboxCalendarFolder -Identity "$($_.PrimarySmtpAddress):\$folder" |
Where-Object { $_.PublishEnabled }
}
# Stop publishing on a specific calendar
Set-MailboxCalendarFolder -Identity "user@contoso.com:\Calendar" -PublishEnabled $false
The folder-name lookup is not decoration. Get-MailboxCalendarFolder wants the folder's real name, and on a mailbox created in Dutch that is :\Agenda, not :\Calendar. Hardcode :\Calendar across a mixed-language tenant and your clean-up script reports a beautifully clean zero. π³π±
The paths that stay open β β
Switching this off is only defensible because the real use cases have better homes. Point users at them in the same breath, or the setting comes back on in six weeks with a business case attached.
Partner free/busy: organization relationships. For the accountant, the sister company, the outsourced developer, configure an organization relationship with that specific tenant (Get-OrganizationRelationship). It is domain-scoped, admin-managed, mutual, and it survives an audit. One relationship beats forty users each sharing a personal link. π€
Public availability: Bookings. For anyone whose job involves outsiders picking a slot, sales, support, an intake desk, a Bookings page exposes bookable time without exposing the calendar. Governed under Org settings β Services β Bookings, which is its own conversation about who may create pages.
One-off scheduling: a scheduling poll. The Outlook poll gathers availability from external participants without either side publishing anything. Most "but I need to share my calendar" requests are actually this. π³οΈ
Caveats β οΈβ
Contacts sharing travels with it. The Default Sharing Policy governs calendar and contacts sharing. Disable it and both stop. If a customer genuinely shares contacts externally, that is a conversation to have first, not a surprise ticket on Monday. π
Organization relationships are untouched. Disabling the sharing policy does nothing to existing organization relationships or on-premises federation. Partner free/busy keeps working. This is a feature, not a gap.
External meeting invitations keep working. Nobody loses the ability to invite an external attendee, see their reply, or receive an invitation from outside. This setting is about browsing a calendar, not about meetings. Say that out loud during change comms, because "we turned off external calendar sharing" reads to the business like "you can no longer meet with customers." π£
Anonymous URLs deserve their own look. If you found Anonymous: in the Domains output, assume something is published and go find it before you close the change. A disabled policy is not a substitute for knowing what was already handed out.
License fit (MKB lens). All of this is Exchange Online Plan 1 and up, so Business Premium covers it with room to spare. There is no upsell here, only a checkbox nobody ever unchecked.
Reversibility. Clean-revert. Re-enabling the policy restores the old behaviour with no residue. Which is precisely why it belongs in drift detection: nothing prevents a well-meaning admin from turning it back on for one user and leaving it on for everyone. π
π‘ SuperVision tipβ
Baseline setting. Golden Master β Admin center β Org settings β Calendar. Same value in every tenant: off.
Tag candidates:
- Sharing-exception mailboxes: per-tenant. The handful of people, if any, with a signed-off reason to share externally.
- Organization relationship domains: per-tenant. Every customer has a different set of partners.
The exception path, done properly. Do not re-enable the default policy for one person. Build a second, narrower policy and assign it only where it is justified:
New-SharingPolicy -Name "Calendar Sharing - FreeBusy Only" `
-Domains "*:CalendarSharingFreeBusySimple" -Enabled $true
Set-Mailbox -Identity user@contoso.com -SharingPolicy "Calendar Sharing - FreeBusy Only"
Note the detail level: times only, no subjects, no locations. An exception is a smaller door, not an open one.
One trap worth planning around: sharing policies are assigned per mailbox, not per group. Entra group membership does not flow into Set-Mailbox, so the exception group is a source of truth that something has to reconcile on a schedule. Automate the reconcile or the group becomes a list of people who lost their exception three reorganisations ago. βοΈ
Drift detection. Weekly is fine. Get-SharingPolicy | Where-Object {$_.Default -and $_.Enabled} returning a result is the signal. Pair it with an alert on the admin-center change, because the person flipping it back is rarely the person who will mention it. π¨
Onboarding. On tenant takeover, run the inventory before the change: which policies exist, which mailboxes have a non-default one, which calendars are published. Turning it off is thirty seconds. Knowing what was already shared is the actual deliverable, and it is the sort of finding that makes the first monthly report land well. π
π₯ Assignment scopeβ
Tenant-wide by default. Exceptions are per-mailbox through a separate, narrower sharing policy, tracked by an exception group and reconciled on a schedule.
π Relatedβ
- π’π§βπΌTS - Default User Permissions: the same reflex one layer down, closing the self-service doors that ship open.
- π€π§βπΌAG - Agent Builder Sharing: the other place where a Share dropdown decides how far your data travels.
Nobody misses this feature. Everybody would miss the incident it makes possible. π