EXT-06: Tracking External Sharing Links
Overview
External sharing links in SharePoint and OneDrive can expose sensitive data if not properly monitored and managed. Anonymous links are particularly risky as they can be forwarded to anyone. This guide helps you gain visibility into existing sharing links, monitor new shares, and remediate risky sharing configurations.
Prerequisites
Required Roles
- Global Administrator - Full access to all settings
- SharePoint Administrator - Can access SharePoint admin center and audit logs
- Compliance Administrator - Access to Microsoft Purview for advanced search
- Security Reader - Read-only access to audit logs
Required Licenses
- Microsoft 365 E3/E5 or Business Premium
- Microsoft Purview (for advanced eDiscovery and DLP)
Time Estimate
- Initial Audit: 60-90 minutes
- Report Configuration: 30 minutes
- Alerting Setup: 20 minutes
Step-by-Step Instructions
Step 1: Enable Audit Logging
Verify unified audit logging is enabled:
- Navigate to Microsoft Purview compliance portal (https://compliance.microsoft.com)
- Go to Audit in the left navigation
- If prompted, click Start recording user and admin activity
- Audit logs are retained for 180 days (E5) or 90 days (E3)
Step 2: Search for Sharing Events
Via Purview Audit Log Search
- Navigate to Purview → Audit → Audit New Search
- Configure search parameters:
- Date range: Last 30 days (or as needed)
- Activities: Search for specific sharing activities:
| Activity | Description |
|---|---|
SharingSet | Sharing configuration changed |
AnonymousLinkCreated | Anyone link created |
AnonymousLinkUsed | Anyone link accessed |
CompanyLinkCreated | Company-wide link created |
SharingInvitationCreated | External user invited |
SharingLinkCreated | Any sharing link created |
SecureLinkCreated | Password-protected link created |
- Click Search
- Export results for analysis
Via PowerShell (Unified Audit Log)
# Connect to Exchange Online (required for Search-UnifiedAuditLog)
Connect-ExchangeOnline
# Search for sharing events
$startDate = (Get-Date).AddDays(-30)
$endDate = Get-Date
$sharingEvents = Search-UnifiedAuditLog -StartDate $startDate -EndDate $endDate `
-Operations "SharingSet", "AnonymousLinkCreated", "SharingInvitationCreated", "SharingLinkCreated" `
-ResultSize 5000
# Parse and format results
$sharingReport = $sharingEvents | ForEach-Object {
$auditData = $_.AuditData | ConvertFrom-Json
[PSCustomObject]@{
Date = $_.CreationDate
User = $_.UserIds
Operation = $_.Operations
SiteUrl = $auditData.SiteUrl
ItemName = $auditData.SourceFileName
ItemUrl = $auditData.ObjectId
TargetUser = $auditData.TargetUserOrGroupName
SharingType = $auditData.EventData
}
}
# Display results
$sharingReport | Format-Table -AutoSize
# Export to CSV
$sharingReport | Export-Csv -Path "SharingAudit.csv" -NoTypeInformation
Step 3: Identify Anonymous Links
Anonymous (Anyone) links are the highest risk. Find all active anonymous links:
Using SharePoint Admin Center Reports
- Navigate to SharePoint admin center (https://admin.microsoft.com/sharepoint)
- Go to Reports → Sharing
- Review the Sharing links report
- Filter by Link type: Anyone
Using PowerShell with PnP
# Connect to SharePoint Online
$siteUrl = "https://yourtenant.sharepoint.com/sites/SiteName"
Connect-PnPOnline -Url $siteUrl -Interactive
# Get all sharing links
$items = Get-PnPListItem -List "Documents" -PageSize 500
$anonymousLinks = @()
foreach ($item in $items) {
$sharingInfo = Get-PnPFileSharingLink -Identity $item
foreach ($link in $sharingInfo) {
if ($link.Link.Type -eq "Anonymous") {
$anonymousLinks += [PSCustomObject]@{
FileName = $item.FieldValues.FileLeafRef
FilePath = $item.FieldValues.FileRef
LinkType = $link.Link.Type
LinkScope = $link.Link.Scope
HasPassword = $link.Link.HasPassword
Expiration = $link.ExpirationDateTime
CreatedBy = $link.Link.CreatedBy
}
}
}
}
$anonymousLinks | Export-Csv -Path "AnonymousLinks.csv" -NoTypeInformation
Write-Host "Found $($anonymousLinks.Count) anonymous links"
Step 4: Audit Externally Shared Files
Find all files shared with external users:
# Using SharePoint Search with external sharing filter
Connect-PnPOnline -Url "https://yourtenant.sharepoint.com" -Interactive
# Search for externally shared content
$searchQuery = "IsDocument:True SharedWithUsersOWSUSER:*#ext#*"
$results = Submit-PnPSearchQuery -Query $searchQuery -MaxResults 500 -SelectProperties "Title", "Path", "SharedWithUsersOWSUSER", "LastModifiedTime"
$externalShares = $results.ResultRows | ForEach-Object {
[PSCustomObject]@{
Title = $_.Title
Path = $_.Path
SharedWith = $_.SharedWithUsersOWSUSER
LastModified = $_.LastModifiedTime
}
}
$externalShares | Export-Csv -Path "ExternallySharedFiles.csv" -NoTypeInformation
Step 5: Set Up Sharing Alerts
Create automated alerts for high-risk sharing:
Microsoft Purview Alert Policy
- Navigate to Purview → Policies → Alert policies
- Click + New alert policy
- Configure:
- Name: "Anonymous Link Created"
- Description: "Alert when anyone link is created"
- Category: Data loss prevention
- Severity: Medium or High
- Activity: AnonymousLinkCreated
- Threshold: Every time this activity occurs
- Email recipients: Security team
- Click Save
Additional Recommended Alerts
| Alert Name | Activity | Severity |
|---|---|---|
| Bulk External Sharing | Multiple SharingSet in 5 minutes | High |
| Sensitive File Shared | SharingSet on classified file | High |
| Anonymous Link to Executive Files | AnonymousLinkCreated on exec folder | Critical |
| External Share to Competitor Domain | SharingInvitationCreated to blocked domain | Critical |
Step 6: Integrate with DLP
Prevent sharing of sensitive content:
- Navigate to Purview → Data loss prevention → Policies
- Create or edit a DLP policy
- Under Locations, include SharePoint and OneDrive
- Configure rules:
- Condition: Content contains sensitive info (PII, financial data, etc.)
- Action: Block external sharing
- User notification: Explain why sharing is blocked
- Enable the policy
Step 7: Create Sharing Reports
Power BI Dashboard (Advanced)
- Export audit log data regularly to storage
- Connect Power BI to audit data
- Create visualizations:
- Sharing trends over time
- Top sharers
- Most shared files
- Anonymous vs authenticated shares
- External domains receiving shares
Scheduled PowerShell Report
# Weekly sharing report - schedule via Task Scheduler or Azure Automation
Connect-ExchangeOnline
$startDate = (Get-Date).AddDays(-7)
$endDate = Get-Date
# Get sharing summary
$sharingEvents = Search-UnifiedAuditLog -StartDate $startDate -EndDate $endDate `
-Operations "SharingSet", "AnonymousLinkCreated", "SharingInvitationCreated" `
-ResultSize 5000
$summary = @{
TotalShareEvents = $sharingEvents.Count
AnonymousLinks = ($sharingEvents | Where-Object { $_.Operations -eq "AnonymousLinkCreated" }).Count
ExternalInvites = ($sharingEvents | Where-Object { $_.Operations -eq "SharingInvitationCreated" }).Count
UniqueUsers = ($sharingEvents | Select-Object -Unique UserIds).Count
DateRange = "$($startDate.ToString('yyyy-MM-dd')) to $($endDate.ToString('yyyy-MM-dd'))"
}
# Generate HTML report
$htmlBody = @"
<h2>Weekly Sharing Activity Report</h2>
<p>Period: $($summary.DateRange)</p>
<table border='1'>
<tr><td>Total Sharing Events</td><td>$($summary.TotalShareEvents)</td></tr>
<tr><td>Anonymous Links Created</td><td>$($summary.AnonymousLinks)</td></tr>
<tr><td>External Invitations</td><td>$($summary.ExternalInvites)</td></tr>
<tr><td>Unique Users Sharing</td><td>$($summary.UniqueUsers)</td></tr>
</table>
"@
# Send email
Send-MailMessage -To "security@company.com" -Subject "Weekly Sharing Report" -Body $htmlBody -BodyAsHtml -SmtpServer "smtp.company.com"
Step 8: Remediate Risky Shares
Remove Specific Anonymous Links
Connect-PnPOnline -Url "https://yourtenant.sharepoint.com/sites/SiteName" -Interactive
# Remove anonymous link from a file
$file = Get-PnPFile -Url "/sites/SiteName/Shared Documents/SensitiveFile.docx"
$links = Get-PnPFileSharingLink -Identity $file
foreach ($link in $links) {
if ($link.Link.Type -eq "Anonymous") {
Remove-PnPFileSharingLink -Identity $file -LinkId $link.Id -Force
Write-Host "Removed anonymous link: $($link.Link.WebUrl)"
}
}
Bulk Anonymous Link Removal
# Remove all anonymous links from a site
$siteUrl = "https://yourtenant.sharepoint.com/sites/TargetSite"
Connect-PnPOnline -Url $siteUrl -Interactive
$lists = Get-PnPList | Where-Object { $_.BaseTemplate -eq 101 } # Document libraries
foreach ($list in $lists) {
$items = Get-PnPListItem -List $list -PageSize 500
foreach ($item in $items) {
$links = Get-PnPFileSharingLink -Identity $item -ErrorAction SilentlyContinue
foreach ($link in $links) {
if ($link.Link.Type -eq "Anonymous") {
Remove-PnPFileSharingLink -Identity $item -LinkId $link.Id -Force
Write-Host "Removed: $($item.FieldValues.FileRef)"
}
}
}
}
Step 9: Monitor Sharing Trends
Track sharing patterns over time:
// Azure Monitor / Sentinel query
OfficeActivity
| where TimeGenerated > ago(30d)
| where Operation in ("SharingSet", "AnonymousLinkCreated", "SharingInvitationCreated")
| summarize Count = count() by Operation, bin(TimeGenerated, 1d)
| render timechart
Step 10: Implement Governance Controls
Sharing Governance Recommendations
| Control | Implementation |
|---|---|
| Disable anonymous links | SharePoint admin center → Sharing settings |
| Require link expiration | Set maximum days for sharing links |
| Restrict external domains | Allow list for trusted domains |
| Enforce site classification | Apply sensitivity labels |
| Educate users | Security awareness training |
Verification Checklist
After implementing sharing visibility:
- Audit logging is enabled and verified
- Initial sharing audit completed
- Anonymous links inventory created
- External sharing inventory created
- Alert policies configured for high-risk sharing
- DLP policies prevent sensitive data sharing
- Weekly/monthly reports are scheduled
- Remediation process documented
- Trend monitoring is operational
- Governance controls are in place
- User education on sharing best practices
Troubleshooting
Issue: Audit log search returns no results
Cause: Audit logging may not be enabled or data hasn't propagated.
Solution:
- Verify audit is enabled in Purview
- Wait up to 24 hours for new events to appear
- Check date range is correct
- Verify you have permission to search audit logs
Issue: Cannot find sharing links for a specific file
Cause: File may not have sharing links or permissions are missing.
Solution:
- Verify you have site collection admin rights
- Check the file directly in SharePoint for sharing status
- Use Graph API for more detailed sharing info:
GET /sites/{site-id}/drive/items/{item-id}/permissions
Issue: Too many audit events to process
Cause: Large environment with high sharing volume.
Solution:
- Narrow date range
- Filter by specific operations
- Export to blob storage for Power BI analysis
- Use Microsoft Defender for Cloud Apps for automated analysis
Issue: Alert policy not triggering
Cause: Policy may be misconfigured or disabled.
Solution:
- Verify policy is enabled
- Check the activity filter matches actual events
- Verify email recipients are correct
- Check spam filters for alert emails
- Review policy in Purview for errors
Issue: Cannot determine who created old anonymous links
Cause: Historical data may be outside audit retention period.
Solution:
- Audit logs have limited retention (90-180 days)
- For older links, check file version history
- Review the link's metadata if available
- Consider the link owner as the file creator
Issue: Sharing reports show inconsistent numbers
Cause: Different tools may count sharing differently.
Solution:
- Use consistent time ranges
- Clarify what's being counted (events vs links vs files)
- Note that modifying sharing creates new events
- Deduplicate by file path when appropriate
Related Resources
Last updated: January 2025