|
| 1 | +# SharePoint Online - Export SharePoint Alerts |
| 2 | + |
| 3 | +## Summary |
| 4 | + |
| 5 | +This PowerShell script scans your SharePoint Online environment and exports a list of all classic SharePoint Alerts configured by users across all site collections. |
| 6 | + |
| 7 | +This is especially useful in preparation for the upcoming retirement of SharePoint Alerts. The script helps administrators audit alert usage, review who is using alerts and where, and prepare to transition to modern alternatives such as SharePoint Rules or Power Automate. |
| 8 | + |
| 9 | +### SharePoint Alerts Retirement Timeline |
| 10 | + |
| 11 | +Microsoft has announced the deprecation and removal of **classic SharePoint Alerts**. Use this script to assess current alert usage and prepare for a smooth transition. |
| 12 | + |
| 13 | +#### Important Dates to Keep in Mind |
| 14 | + |
| 15 | +- **July 2025** – Creation of new SharePoint alerts disabled for **new tenants** |
| 16 | +- **September 2025** – Creation of new alerts disabled for **existing tenants** |
| 17 | +- **October 2025** – Existing alerts will **expire after 30 days** (they can be manually re-enabled) |
| 18 | +- **July 2026** – **SharePoint Alerts removed entirely** |
| 19 | + |
| 20 | +After these dates, organisations should use modern alternatives like SharePoint Rules or Power Automate. |
| 21 | + |
| 22 | +### Features |
| 23 | + |
| 24 | +- Connects to all site collections in your tenant |
| 25 | +- Retrieves classic alerts created by users |
| 26 | +- Outputs a clean, structured CSV file with alert metadata |
| 27 | +- Logs connection or permission errors to a separate file |
| 28 | + |
| 29 | +### Sample Output |
| 30 | + |
| 31 | +Below is an example of the exported `SharePointAlerts_Report.csv` when opened in Excel: |
| 32 | + |
| 33 | + |
| 34 | + |
| 35 | +*** |
| 36 | + |
| 37 | +# [PnP PowerShell](#tab/pnpps) |
| 38 | +```powershell |
| 39 | +# ============================================================ |
| 40 | +# SharePoint Alerts Export Script |
| 41 | +# Preferred Auth: Certificate |
| 42 | +# Alternate Auth: Interactive |
| 43 | +# ============================================================ |
| 44 | +
|
| 45 | +# === Configurable Variables === |
| 46 | +$clientId = "<your-client-id>" |
| 47 | +$certPath = "<path-to-certificate-folder>" |
| 48 | +$certName = "<your-certificate-name>.pfx" |
| 49 | +$tenant = "<your-tenant-id>" |
| 50 | +
|
| 51 | +$basePath = "<your-output-directory>" # Example: "C:\Reports" |
| 52 | +$outputCsvName = "SharePointAlerts_Report.csv" |
| 53 | +$errorLogName = "SharePointAlerts_Errors.csv" |
| 54 | +
|
| 55 | +$tenantAdminUrl = "https://<your-tenant>-admin.sharepoint.com" |
| 56 | +$outputCsvPath = Join-Path -Path $basePath -ChildPath $outputCsvName |
| 57 | +$errorLogPath = Join-Path -Path $basePath -ChildPath $errorLogName |
| 58 | +
|
| 59 | +# === Create output folder if it doesn't exist === |
| 60 | +if (-not (Test-Path -Path $basePath)) { |
| 61 | + New-Item -ItemType Directory -Path $basePath -Force | Out-Null |
| 62 | +} |
| 63 | +
|
| 64 | +# === Arrays to collect results and errors === |
| 65 | +$alertResults = @() |
| 66 | +$errorLog = @() |
| 67 | +
|
| 68 | +# === Connect to SharePoint Admin Center === |
| 69 | +# Preferred: Certificate-based authentication |
| 70 | +Connect-PnPOnline -Url $tenantAdminUrl -ClientId $clientId -Tenant $tenant -CertificatePath "$certPath\$certName" |
| 71 | +
|
| 72 | +# Alternate: Interactive authentication |
| 73 | +# Connect-PnPOnline -Url $tenantAdminUrl -Interactive |
| 74 | +
|
| 75 | +# === Retrieve all site collections === |
| 76 | +$sites = Get-PnPTenantSite |
| 77 | +
|
| 78 | +foreach ($site in $sites) { |
| 79 | + Write-Host "`nProcessing site: $($site.Url)" -ForegroundColor Cyan |
| 80 | +
|
| 81 | + # === Connect to each site === |
| 82 | + # Preferred: Certificate-based authentication |
| 83 | + Connect-PnPOnline -Url $site.Url -ClientId $clientId -Tenant $tenant -CertificatePath "$certPath\$certName" |
| 84 | +
|
| 85 | + # Alternate (manual run): Interactive authentication |
| 86 | + # Connect-PnPOnline -Url $site.Url -Interactive |
| 87 | +
|
| 88 | + try { |
| 89 | + $alerts = Get-PnPAlert -AllUsers -InformationAction SilentlyContinue |
| 90 | + if ($alerts) { |
| 91 | + Write-Host "Found $($alerts.Count) alerts in: $($site.Url)" -ForegroundColor Green |
| 92 | + foreach ($alert in $alerts) { |
| 93 | + $user = Get-PnPUser -Identity $alert.UserId |
| 94 | + $alertResults += [PSCustomObject]@{ |
| 95 | + SiteUrl = $site.Url |
| 96 | + AlertFrequency = $alert.AlertFrequency |
| 97 | + AlertType = $alert.AlertType |
| 98 | + AlertTime = $alert.AlertTime |
| 99 | + AlwaysNotify = $alert.AlwaysNotify |
| 100 | + DeliveryChannels = $alert.DeliveryChannels |
| 101 | + EventType = $alert.EventType |
| 102 | + Filter = $alert.Filter |
| 103 | + ID = $alert.ID |
| 104 | + Status = $alert.Status |
| 105 | + Title = $alert.Title |
| 106 | + UserId = $alert.UserId |
| 107 | + UserName = $user.Title |
| 108 | + UserEmail = $user.Email |
| 109 | + DispFormUrl = $alert.Properties["dispformurl"] |
| 110 | + } |
| 111 | + } |
| 112 | + } else { |
| 113 | + Write-Host "No alerts found." -ForegroundColor Yellow |
| 114 | + } |
| 115 | + } |
| 116 | + catch { |
| 117 | + $errorMessage = "Error retrieving alerts for site: $($site.Url)." |
| 118 | + Write-Host $errorMessage -ForegroundColor Red |
| 119 | +
|
| 120 | + $errorLog += [PSCustomObject]@{ |
| 121 | + SiteUrl = $site.Url |
| 122 | + ErrorMessage = $_.Exception.Message |
| 123 | + ErrorDetails = $_.Exception.StackTrace |
| 124 | + } |
| 125 | + } |
| 126 | +} |
| 127 | +
|
| 128 | +# === Export results to CSV === |
| 129 | +$alertResults | Export-Csv -Path $outputCsvPath -NoTypeInformation -Encoding UTF8 |
| 130 | +Write-Host "`nReport exported to: $outputCsvPath" -ForegroundColor Green |
| 131 | +
|
| 132 | +# === Export errors if any === |
| 133 | +if ($errorLog.Count -gt 0) { |
| 134 | + $errorLog | Export-Csv -Path $errorLogPath -NoTypeInformation -Encoding UTF8 |
| 135 | + Write-Host "Error log exported to: $errorLogPath" -ForegroundColor Yellow |
| 136 | +} else { |
| 137 | + Write-Host "No errors encountered." -ForegroundColor Green |
| 138 | +} |
| 139 | +
|
| 140 | +# === Disconnect session === |
| 141 | +Disconnect-PnPOnline |
| 142 | +``` |
| 143 | +[!INCLUDE [More about PnP PowerShell](../../docfx/includes/MORE-PNPPS.md)] |
| 144 | + |
| 145 | +*** |
| 146 | + |
| 147 | +## Contributors |
| 148 | + |
| 149 | +| Author | |
| 150 | +|-----------| |
| 151 | +| [Tanel Vahk](https://www.linkedin.com/in/tvahk/) | |
| 152 | + |
| 153 | +[!INCLUDE [DISCLAIMER](../../docfx/includes/DISCLAIMER.md)] |
| 154 | +<img src="https://m365-visitor-stats.azurewebsites.net/script-samples/scripts/spo-sharepoint-alerts-audit" aria-hidden="true" /> |
0 commit comments