Understanding who shares what with whom sits at the core of Teams governance, and it is also, candidly, one of the harder disciplines to get right. Teams offers several routes to external sharing: guest access, file sharing in the file service that underpins Teams file storage, screen sharing during meetings, and external access federation. Each of those routes leaves its own signature in the audit logs.

This article walks through locating and reading the principal audit events that signal external sharing activity, and through folding a recurring external sharing review into your governance cadence.

Where Audit Logs Are Found

Audit logging for the cloud suite is consolidated in the compliance portal, under Audit > Search. PowerShell exposes the same data through the Search-UnifiedAuditLog cmdlet, which suits bulk queries and automated reporting far better.

Events reach the audit log from every cloud suite service, Teams, the file service and the identity service among them. Where external sharing is concerned, these are the sources that matter most:

  • the file service and the personal file store: Sharing events, changes to permissions, and guest user actions on files that have been shared
  • Teams: Events for guests being added, messages involving externals, and meeting participation
  • the directory service: Creation and removal of guest accounts, plus B2B invitation events
  • Teams membership changes: Additions and removals of members, guests included, which land as Teams and directory audit events rather than as file service sharing records.
  • Cross-tenant access changes: Modifications to partner configuration that expand or restrict B2B direct connect; a file-sharing query will never surface these.

Principal Audit Events Behind External Sharing

Guest user added to team. When somebody new joins a team, the MemberAdded and TeamCreated Teams audit events record it. To isolate guest additions, look at MemberAdded events in which the incoming user's UPN carries a #EXT# suffix, which is the identity service's standard shape for guest accounts: user_externaldomain.com#EXT#@yourtenant.onexample.com.

File shared with external user. File sharing is recorded by the file service audit events. Sending a sharing invitation to someone external raises SharingInvitationCreated; generating an anonymous sharing link raises AnonymousLinkCreated. Narrow the results to events whose TargetUserOrGroupType reads "Guest" or "External."

External user accessed a file. Filter the file service FileAccessed event down to guest activity and you get a record of which files external users opened, and when. It serves post-incident enquiry ("did the guest who left ever open the sensitive project folder?") as well as routine monitoring of external behaviour.

Meeting with external attendees. Attendance is captured by the Teams meeting events, but telling externals from internals means filtering on user type or UPN suffix. Per-meeting attendance detail comes from the MeetingParticipantDetail event, reached through the Teams Admin Center's meeting reports rather than the unified audit log, and it flags whether each attendee was internal, a guest, or anonymous.

Running Audit Log Queries in PowerShell

Once external sharing audits become repetitive, querying the unified audit log in PowerShell beats searching through the compliance portal UI. A few examples worth keeping:

# Find all guest user additions to Teams in the last 30 days
$results = Search-UnifiedAuditLog -StartDate (Get-Date).AddDays(-30) -EndDate (Get-Date) `
 -RecordType Teams -Operations "MemberAdded"
$results | Where-Object { $_.AuditData -like '*#EXT#*' } | Select-Object -ExpandProperty AuditData | ConvertFrom-Json
# Find external file sharing events in the last 30 days
Search-UnifiedAuditLog -StartDate (Get-Date).AddDays(-30) -EndDate (Get-Date) `
 -RecordType the file service -Operations "SharingInvitationCreated","AnonymousLinkCreated" `
 -ResultSize 5000

Establishing a Recurring External Sharing Review

A recurring external sharing review belongs in the Teams governance cadence as a matter of course, whether monthly or quarterly, shaped by how much external collaboration takes place and how much risk the organisation will stomach.

A workable monthly review covers:

  • Guest accounts created during the preceding month: confirm every one was deliberate and complies with your guest access policy
  • Guest accounts idle for 90 days or more: raise them with team owners, and remove any that nobody can justify keeping
  • Anonymous sharing links generated in the preceding month: check that each one is legitimate, since some organisations ban anonymous links outright
  • Files exposed outside the organisation from high-sensitivity teams: assess whether that sharing was authorised and matched the team's sensitivity classification

Alerting Automatically on External Sharing Events

Periodic manual audits should not carry the whole load. Alert policies in the compliance portal can watch high-risk external sharing events instead, firing, say, when an anonymous sharing link appears on a site carrying a "Confidential" sensitivity label, or when a guest is added to a team classified as a restricted workspace.

You define alert policies at compliance portal > Policies > Alert policies. When matching events land in the log, notifications go to nominated recipients, giving near-real-time sight of likely policy breaches and removing the need to read logs by hand continuously.

An Alert So Noisy That Nobody Reads It

The value of an external-sharing alert rests entirely on its threshold. In a tenant that genuinely collaborates, Teams and the file service generate a heavy stream of sharing and membership events. Alert on every guest addition and the mailbox owner learns to bin the message. Alert too quietly and the slide deck praises the control while the one share that mattered goes unseen.

An IT department at a university, covering 8,000 accounts, raised an alert for any anonymous link created on a site labelled internal. Week one produced a workable handful, because that label sat on only a subset of sites and anonymous links were already being discouraged. A template supplied the second alert, which triggered on every guest invitation across the tenant. Student project teams bring guests in constantly. Within days that second alert was muted, and nobody wrote the muted state down. Six weeks later, a batch of personal mail addresses invited into a staff team generated events that no one saw.

Build the alert around the exception rather than the permitted route. Where owners may add guests, alert instead on a guest landing in a team whose label forbids guests, or on a single actor adding more than a defined number of guests inside an hour. Where labelled sites ban anonymous links, scope the alert to that link type and that label rather than to every share. Trigger it deliberately and confirm the message lands in a mailbox somebody actually staffs.

How long the audit log is retained belongs in the review design. Start a monthly review after the log has rolled off and you are reviewing nothing at all. Establish how far back your licence holds audit data, then pull the export on a schedule inside that window. A PowerShell search that "worked last year" fails quietly the moment its date range reaches past the log's retention.

Maintain a short list of saved queries: guests added over the last 30 days, anonymous links on labelled sites, and the file service site behind the team being shared or forwarded to a previously unseen external domain. Three queries that somebody actually runs beat a catalogue of thirty that nobody opens. Attach the outcome, including a nil outcome, to the review note so the quiet month is visible.

Identify by name who triages each alert, and who covers when they are away. Sending an alert to a shared mailbox does not remove the need for a rota. Silence the automation you already know about. A flow that pulls a partner in every Monday will swamp the alert unless its app id is excluded and reviewed on its own. Treat a guest add and an external share link as distinct: they are separate events demanding separate responses. Where the alert destination is email, verify that the mail is not itself being swept into a folder nobody expands. Log muted or disabled alerts as findings in their own right. A disabled alert is a control that has been switched off. Run one alert drill per quarter by carrying out the triggering action in a test team. A query nobody has proven will fail in the week you depend on it. A nil result still counts as a result. File it, otherwise the following month reads as though the review was skipped. State the thresholds inside the alert description. Whoever inherits this later should not have to guess why the alert is quieter than the log. Fire test alerts during working hours, so the person meant to receive them is there to confirm. Where an application and a person generate guest adds at volumes an order of magnitude apart, split them into two alerts. Save the audit log search behind the monthly review rather than rebuilding it from a screenshot of the filter pane. Should the licence cut audit retention shorter, the review frequency has to shorten to match. A sharing event on the site that backs a team is still a Teams matter for that team's owner, so route it to them. Give every mute rule an expiry; a mute with no expiry is precisely how the important alert stays silent. Reconcile the alert count against the raw event count at least once. A wide gap points to a wrong filter or dropped mail. Write down which test team serves the drills, so live alerts are not mistaken for exercise traffic. Fold new labels into the alert filter within the same change that introduces the label, or the opening weeks run unwatched. Keep the KQL or the portal filter text in the runbook. A review that relies on clicking the same blades from memory will miss a checkbox.

Marcus Whitfield

Marcus Whitfield

IT Security & Compliance Analyst

Marcus's work sits at the crossing point of Teams security and regulatory compliance.