1. The Unfiltered Reality of Turning On M365 AI
A few months ago, an IT Director reached out in a mild panic. His engineering organization had rolled out Microsoft 365 Copilot licenses to department leads over the weekend. By Monday morning, a junior coordinator typed “What are the highest executive salaries?” into Copilot—and the AI handed over a formatted summary of executive compensation spreadsheets stored inside an unlisted HR folder.
Here is what Microsoft sales pitch decks don’t emphasize: Copilot and custom M365 Agents don’t bypass permissions—they respect them with terrifying accuracy.
If an administrator created a SharePoint site six years ago and selected "Everyone except external users" to bypass ticket delays, that data is no longer hidden by obscure folder structures. The moment you enable AI indexing, permission debt becomes instantly searchable text. Before turning on AI licenses, you must audit your tenant’s over-sharing footprint.
2. Technical Architecture & Governance Workflow
To safely evaluate your tenant prior to deploying M365 Agents, follow this structured four-stage governance workflow:
3. Prerequisites & Graph Permissions
Before executing the scan script, ensure your administrative workstation is equipped with the updated Graph SDK modules and appropriate administrative permissions.
| Microsoft Graph Scope | Permission Type | Administrative Purpose |
|---|---|---|
Sites.Read.All |
Delegated / Application | Required to enumerate site collections, subsites, and permission structures. |
Directory.Read.All |
Delegated / Application | Resolves tenant group objects to verify ‘Everyone Except External Users’ settings. |
4. Production PowerShell Governance Audit Script
Run the native PowerShell script below from an administrative workstation to generate a CSV report of your tenant’s risk posture:
<#
.SYNOPSIS
M365 Tenant AI Readiness & Over-Sharing Audit Tool
.DESCRIPTION
Scans SharePoint Online site collections via Microsoft Graph SDK to flag
public access and broad sharing settings prior to M365 Copilot / Agent rollout.
.AUTHOR
Dheerajtheblogger | Innovation Guru (https://dsinnovationguru.com)
#>
[CmdletBinding()]
param (
[Parameter(Mandatory = $false)]
[string]$CsvPath = "C:\Reports\M365_AI_Readiness_Audit.csv"
)
# 1. Connect to Graph API safely
Write-Host "[+] Connecting to Microsoft Graph API..." -ForegroundColor Cyan
$RequiredScopes = @("Sites.Read.All", "Directory.Read.All")
try {
Connect-MgGraph -Scopes $RequiredScopes -ErrorAction Stop
Write-Host "[✓] Authenticated successfully." -ForegroundColor Green
}
catch {
Write-Error "[!] Authentication failed: $_"
exit
}
# 2. Gather Site Collections
Write-Host "[+] Fetching SharePoint Site Collections..." -ForegroundColor Cyan
$Sites = Get-MgSite -All -Property Id, DisplayName, WebUrl, SharepointIds, SiteCollection
$AuditResults = [System.Collections.Generic.List[PSObject]]::new()
$TotalSites = $Sites.Count
$Count = 0
foreach ($Site in $Sites) {
$Count++
Write-Progress -Activity "Scanning Sites for AI Exposure" -Status "Processing site $Count of $TotalSites : $($Site.DisplayName)" -PercentComplete (($Count / $TotalSites) * 100)
# Exclude personal OneDrive repositories
if ($Site.WebUrl -like "*/personal/*" -or [string]::IsNullOrWhiteSpace($Site.DisplayName)) { continue }
$RiskLevel = "Low"
$RiskFactors = [System.Collections.Generic.List[string]]::new()
# Evaluate Data Access Governance
if ($null -ne $Site.SiteCollection.DataAccessGovernance) {
if ($Site.SiteCollection.DataAccessGovernance.EveryOneExceptExternalUsersAccess -eq "Granted") {
$RiskLevel = "High"
$RiskFactors.Add("Tenant-Wide Access Granted ('Everyone Except External')")
}
}
if ($Site.WebUrl -notlike "*-my.sharepoint.com*") {
$RiskFactors.Add("Standard Repository: Verify Sharing Links")
}
$RiskFactorString = if ($RiskFactors.Count -gt 0) { $RiskFactors -join " | " } else { "Clean / Restricted" }
# Construct Record
$AuditObject = [PSCustomObject]@{
SiteName = $Site.DisplayName
SiteUrl = $Site.WebUrl
RiskLevel = $RiskLevel
RiskFactors = $RiskFactorString
AuditedDate = (Get-Date -Format "yyyy-MM-dd HH:mm:ss")
}
$AuditResults.Add($AuditObject)
}
# 3. Export CSV Data
$TargetDir = Split-Path -Path $CsvPath -Parent
if (-not (Test-Path -Path $TargetDir)) {
New-Item -ItemType Directory -Path $TargetDir -Force | Out-Null
}
$AuditResults | Export-Csv -Path $CsvPath -NoTypeInformation -Encoding UTF8
Write-Host "[✓] CSV report generated successfully at: $CsvPath" -ForegroundColor Green
5. Tiered L1–L3 Remediation Playbook
Once high-exposure sites are flagged by the audit script, support teams can execute these non-disruptive remediation steps:
Tier 1 (L1 Service Desk): Disable Anonymous Links
Restrict anonymous external sharing links immediately across flagged repositories:
Set-SPOSite -Identity "https://yourtenant.sharepoint.com/sites/FinanceProjects" -SharingCapability Disabled
Tier 2 (L2 SysAdmin): Enable Restricted Access Control (RAC)
Apply Restricted Access Control (RAC) policies so M365 Agents cannot index repository content beyond assigned M365 Group members:
# Enable RAC at the tenant level Set-SPOTenant -EnableRestrictedAccessControl $true # Restrict sensitive site scope Set-SPOSite -Identity "https://yourtenant.sharepoint.com/sites/ExecutiveHR" -RestrictedAccessControl $true
Tier 3 (L3 / Security Architect): Purview DLP Enforcement
Deploy Microsoft Purview Data Loss Prevention (DLP) auto-labeling rules to tag confidential assets, automatically excluding sensitive documents from AI Semantic Indexing.
6. Final Thoughts & Next Steps
Prepping your tenant for AI isn’t a one-and-done project—it’s an ongoing operational habit. I recommend setting up a scheduled task to run this audit script once a month or feeding the output directly into a Power BI dashboard for your security committee.
If you ran this script in your environment, what was your most unexpected discovery? Drop your thoughts or questions in the comments below!
