SharePoint / Guide 3
SharePoint Online tips
PnP.PowerShell and the SPO module in practice: paging, batching, sharing, recovery, storage.
1. Two modules, two jobs
Use the SPO module (Connect-SPOService) for tenant and site-collection settings: sharing, storage, lock state, hub sites, deleted sites. Use PnP.PowerShell (Connect-PnPOnline) for anything inside a site: lists, files, permissions, pages, provisioning. Trying to do content work with the SPO module is the most common dead end.
Connect-SPOService -Url https://sharepointonline-admin.ravindran.in
Connect-PnPOnline -Url https://sharepointonline.ravindran.in/sites/HR -ClientId $env:PNP_CLIENT_ID -Interactive
2. Page through big lists
Get-PnPListItem -List "Documents" -PageSize 500 -Fields FileRef, Modified
Without -PageSize, a large list will fail on the 5,000 list view threshold. In SharePoint Online that threshold can't be changed, even though a list can hold millions of items. Indexed columns and paging are how you work with it.
3. Batch your writes
Adding or updating thousands of items one call at a time is slow and gets throttled. Batch them:
$batch = New-PnPBatch
foreach ($row in Import-Csv .\items.csv) {
Add-PnPListItem -List "Assets" -Values @{ Title = $row.Title; Location = $row.Location } -Batch $batch
}
Invoke-PnPBatch -Batch $batch
4. Respect throttling
HTTP 429 and 503 responses mean you're being throttled. PnP.PowerShell retries automatically, but you can help: run heavy jobs outside business hours, avoid running many parallel sessions against the same site, and use search or Graph for read-only reporting instead of crawling every item.
5. Use search for fast tenant-wide reports
Search indexes almost everything already. It's often the fastest way to answer "where is X":
Submit-PnPSearchQuery -Query "contentclass:STS_Site" -All -SelectProperties Title, Path, LastModifiedTime
Submit-PnPSearchQuery -Query "filetype:pst OR filetype:iso" -All
6. Force a re-crawl after schema changes
Changed a managed property mapping or column? Request a reindex instead of waiting:
Request-PnPReIndexList -Identity "Contracts"
Request-PnPReIndexWeb
7. Restore deleted sites (within 93 days)
Get-SPODeletedSite
Restore-SPODeletedSite -Identity https://sharepointonline.ravindran.in/sites/OldProject
For a user who deleted hundreds of files by mistake (or a sync client gone wrong), see Restore-SPORecycleBinByUser.ps1.
8. Control sharing per site
Tenant settings are the ceiling; each site can be more restrictive:
Set-SPOSite -Identity https://sharepointonline.ravindran.in/sites/Legal -SharingCapability ExistingExternalUserSharingOnly
# Disabled | ExistingExternalUserSharingOnly | ExternalUserSharingOnly | ExternalUserAndGuestSharing
Run Get-SPOSiteInventory.ps1 to see which sites allow "Anyone" links.
9. Get storage back from version history
Versions of large files (videos, CAD, big Excel models) quietly consume a lot of tenant storage. Options, from least to most hands-on:
- Newer SPO module versions support automatic version trimming at tenant or site level (
EnableAutoExpirationVersionTrimonSet-SPOTenant/Set-SPOSite) and site-level batch delete jobs (New-SPOSiteFileVersionBatchDeleteJob). CheckGet-Helpon your installed module version for the exact parameters. - For a single library, use
Remove-SPOOldFileVersions.ps1and always run it with-WhatIffirst.
10. Temporarily grant yourself site collection admin
Set-SPOUser -Site https://sharepointonline.ravindran.in/sites/HR -LoginName admin@ravindran.in -IsSiteCollectionAdmin $true
# ... do the work ...
Set-SPOUser -Site https://sharepointonline.ravindran.in/sites/HR -LoginName admin@ravindran.in -IsSiteCollectionAdmin $false
Remove yourself afterwards. It's cleaner for audits and for the site owners.
11. Hub sites for navigation and branding
Register-SPOHubSite -Site https://sharepointonline.ravindran.in/sites/Intranet -Principals $null
Add-SPOHubSiteAssociation -Site https://sharepointonline.ravindran.in/sites/HR -HubSite https://sharepointonline.ravindran.in/sites/Intranet
Hubs replace most of what subsites were used for. Build flat, and connect with hubs.
12. Copy a site's structure with PnP provisioning
# From the source site
Get-PnPSiteTemplate -Out .\ProjectTemplate.xml -Handlers Lists, Fields, ContentTypes, Navigation
# On the target site
Invoke-PnPSiteTemplate -Path .\ProjectTemplate.xml
13. Lock a site during migration or legal hold
Set-SPOSite -Identity https://sharepointonline.ravindran.in/sites/Archive -LockState ReadOnly
# Unlock | ReadOnly | NoAccess
14. Custom script: enable only as long as you need it
Some legacy tasks need DenyAddAndCustomizePages turned off on a site. Turn it off, do the work, and let it go back on. Microsoft has also been tightening this setting over time, so don't build processes that depend on it staying off.
Set-SPOSite -Identity https://sharepointonline.ravindran.in/sites/Legacy -DenyAddAndCustomizePages $false