SharePoint Online PnP PowerShell & Graph API Script Library 2026 | LoveSharePoint

COMPLETE SCRIPT LIBRARY • 2026 PRODUCTION EDITION

SharePoint Online PnP PowerShell & Graph API Master Script Hub

Comprehensive repository of production-tested PnP PowerShell scripts, Microsoft Graph REST API automation, SPO governance policies, and tenant-to-tenant migration scripts compiled by LoveSharePoint Team.

⏱️ UPDATE SCHEDULE: BI-WEEKLY (EVERY 2 WEEKS) REFRESH

⚡ 1. PnP PowerShell Administration & Management Scripts

๐Ÿ“œ 1.1 Export SharePoint Online Site & Subsite Permissions to CSV
# ==============================================================================
# Script: Export SharePoint Online Site Permissions to CSV (Recursive)
# Author: LoveSharePoint Team
# Requires: PnP.PowerShell 2.x+
# ==============================================================================

Import-Module PnP.PowerShell

$SiteUrl = "https://yourtenant.sharepoint.com/sites/EnterpriseHub"
$ReportPath = "C:\Reports\SPO_Site_Permissions_Report.csv"

Connect-PnPOnline -Url $SiteUrl -Interactive

$PermissionsReport = @()
$Web = Get-PnPWeb -Includes RoleAssignments

foreach ($RoleAssignment in $Web.RoleAssignments) {
    Get-PnPProperty -ClientObject $RoleAssignment -Property Member, RoleDefinitionBindings
    
    foreach ($RoleDef in $RoleAssignment.RoleDefinitionBindings) {
        $PermissionsReport += [PSCustomObject]@{
            SiteUrl    = $SiteUrl
            Principal  = $RoleAssignment.Member.Title
            UserType   = $RoleAssignment.Member.PrincipalType
            RoleGiven  = $RoleDef.Name
            ReportDate = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")
        }
    }
}

$PermissionsReport | Export-Csv -Path $ReportPath -NoTypeInformation
Write-Host "✅ Permissions Report exported successfully to $ReportPath!" -ForegroundColor Green
๐Ÿ“Š 1.2 Tenant-Wide SharePoint Site Storage & Quota Breakdown Audit
# ==============================================================================
# Script: Tenant-Wide SharePoint Site Storage Audit & Quota Breakdown
# Author: LoveSharePoint Team
# ==============================================================================

$AdminUrl = "https://yourtenant-admin.sharepoint.com"
Connect-PnPOnline -Url $AdminUrl -Interactive

$AllSites = Get-PnPTenantSite -Filter "Url -like '/sites/'"
$StorageReport = @()

foreach ($Site in $AllSites) {
    $StorageReport += [PSCustomObject]@{
        SiteTitle     = $Site.Title
        SiteUrl       = $Site.Url
        StorageMB     = [math]::Round($Site.StorageUsageCurrent, 2)
        StorageGB     = [math]::Round(($Site.StorageUsageCurrent / 1024), 2)
        QuotaGB       = [math]::Round(($Site.StorageMaximumLevel / 1024), 2)
        PercentUsed   = [math]::Round((($Site.StorageUsageCurrent / $Site.StorageMaximumLevel) * 100), 2)
        LastModified  = $Site.LastContentModifiedDate
    }
}

$StorageReport | Sort-Object StorageMB -Descending | Export-Csv -Path "C:\Reports\Tenant_Storage_Audit.csv" -NoTypeInformation
Write-Host "✅ Tenant Storage Audit Complete!" -ForegroundColor Green
๐Ÿงน 1.3 Audit & Bulk Remove External Guest Users Across Site Collections
# ==============================================================================
# Script: Audit & Remove Inactive External Guest Users in SharePoint Online
# Author: LoveSharePoint Team
# ==============================================================================

$AdminUrl = "https://yourtenant-admin.sharepoint.com"
Connect-PnPOnline -Url $AdminUrl -Interactive

$GuestUsers = Get-PnPUser | Where-Object { $_.LoginName -like "*#ext#*" }
$GuestReport = @()

foreach ($Guest in $GuestUsers) {
    $GuestReport += [PSCustomObject]@{
        DisplayName = $Guest.Title
        Email       = $Guest.Email
        LoginName   = $Guest.LoginName
        Id          = $Guest.Id
    }
    # Uncomment to bulk remove: Remove-PnPUser -Identity $Guest.Id -Force
}

$GuestReport | Export-Csv -Path "C:\Reports\External_Guests_Audit.csv" -NoTypeInformation
Write-Host "✅ Audit complete. Found $($GuestUsers.Count) external guest users." -ForegroundColor Green
๐Ÿ“ 1.4 Export All Document Libraries & File Counts across Tenant
# ==============================================================================
# Script: Export Document Libraries, Folder Structure & Item Counts
# Author: LoveSharePoint Team
# ==============================================================================

$SiteUrl = "https://yourtenant.sharepoint.com/sites/Marketing"
Connect-PnPOnline -Url $SiteUrl -Interactive

$DocLibs = Get-PnPList | Where-Object { $_.BaseTemplate -eq 101 -and $_.Hidden -eq $false }
$LibReport = @()

foreach ($Lib in $DocLibs) {
    $LibReport += [PSCustomObject]@{
        LibraryName  = $Lib.Title
        ItemCount    = $Lib.ItemCount
        LastModified = $Lib.LastItemModifiedDate
        DefaultUrl   = $Lib.RootFolder.ServerRelativeUrl
    }
}

$LibReport | Export-Csv -Path "C:\Reports\Library_File_Counts.csv" -NoTypeInformation
Write-Host "✅ Document Library export complete!" -ForegroundColor Green

๐Ÿ”ท 2. Microsoft Graph API Automation Scripts

⚡ 2.1 Microsoft Graph REST API OAuth Token & M365 Group Creator
# ==============================================================================
# Script: Microsoft Graph API OAuth 2.0 Bearer Token & Automated Team Site Creation
# Author: LoveSharePoint Team
# ==============================================================================

$TenantId     = "your-tenant-id-guid"
$ClientId     = "your-app-client-id-guid"
$ClientSecret = "your-app-client-secret"

# 1. Fetch OAuth 2.0 Access Token
$TokenBody = @{
    Grant_Type    = "client_credentials"
    Scope         = "https://graph.microsoft.com/.default"
    Client_Id     = $ClientId
    Client_Secret = $ClientSecret
}

$TokenResponse = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenantId/oauth2/v2.0/token" -Method Post -Body $TokenBody
$AccessToken   = $TokenResponse.access_token

$Headers = @{
    "Authorization" = "Bearer $AccessToken"
    "Content-Type"  = "application/json"
}

# 2. Create M365 Group with Unified SharePoint Site
$GroupPayload = @{
    displayName        = "AI Architecture Steering Group"
    mailNickname       = "ai-architecture-group"
    description        = "Enterprise AI & SharePoint Governance Group by LoveSharePoint"
    groupTypes         = @("Unified")
    mailEnabled        = $true
    securityEnabled    = $false
} | ConvertTo-Json

$NewGroup = Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/groups" -Method Post -Headers $Headers -Body $GroupPayload
Write-Host "✅ M365 Group & SharePoint Team Site Created! Group ID: $($NewGroup.id)" -ForegroundColor Green
๐Ÿ‘ค 2.2 Microsoft Graph API Batch User Licensing & Service Plan Audit
# ==============================================================================
# Script: Query Active Users & Assigned Licenses via Microsoft Graph API
# Author: LoveSharePoint Team
# ==============================================================================

$GraphUri = "https://graph.microsoft.com/v1.0/users?`$select=displayName,userPrincipalName,assignedLicenses,accountEnabled"
$UsersResponse = Invoke-RestMethod -Uri $GraphUri -Method Get -Headers $Headers

$UserLicenses = @()
foreach ($User in $UsersResponse.value) {
    $UserLicenses += [PSCustomObject]@{
        Name           = $User.displayName
        UPN            = $User.userPrincipalName
        IsEnabled      = $User.accountEnabled
        LicenseCount   = $User.assignedLicenses.Count
    }
}

$UserLicenses | Export-Csv -Path "C:\Reports\M365_User_Licenses.csv" -NoTypeInformation
Write-Host "✅ User Licensing Audit Exported!" -ForegroundColor Green

๐Ÿ›ก️ 3. SPO Governance, Security & Policy Control Scripts

๐Ÿ”’ 3.1 Bulk Set External Sharing Capabilities across Site Collections
# ==============================================================================
# Script: Enforce Strict External Sharing Policies Across SharePoint Sites
# Author: LoveSharePoint Team
# ==============================================================================

$AdminUrl = "https://yourtenant-admin.sharepoint.com"
Connect-PnPOnline -Url $AdminUrl -Interactive

# Set sharing capability to ExistingGuestsOnly (Disables Anonymous links)
$TargetSite = "https://yourtenant.sharepoint.com/sites/Finance"
Set-PnPTenantSite -Url $TargetSite -SharingCapability ExistingGuestsOnly

Write-Host "✅ External sharing restricted to ExistingGuestsOnly for $TargetSite" -ForegroundColor Green
๐Ÿ” 3.2 Lock Inactive Site Collections to Read-Only Mode
# ==============================================================================
# Script: Apply Read-Only Lock State to Archived SharePoint Sites
# Author: LoveSharePoint Team
# ==============================================================================

$AdminUrl = "https://yourtenant-admin.sharepoint.com"
Connect-PnPOnline -Url $AdminUrl -Interactive

$ArchiveSite = "https://yourtenant.sharepoint.com/sites/Project2023Archive"
Set-PnPTenantSite -Url $ArchiveSite -LockState ReadOnly

Write-Host "✅ Site $ArchiveSite successfully locked in ReadOnly state." -ForegroundColor Green

๐Ÿš€ 4. Tenant Migration Verification & Post-Migration Scripts

๐Ÿ” 4.1 Post-Migration Document Count & Folder Comparison Verification
# ==============================================================================
# Script: Source vs Target SharePoint Document Count Verification
# Author: LoveSharePoint Team
# ==============================================================================

$SourceUrl = "https://sourcetenant.sharepoint.com/sites/HR"
$TargetUrl = "https://targettenant.sharepoint.com/sites/HR"

# Source Count
Connect-PnPOnline -Url $SourceUrl -Interactive
$SourceCount = (Get-PnPList -Identity "Shared Documents").ItemCount

# Target Count
Connect-PnPOnline -Url $TargetUrl -Interactive
$TargetCount = (Get-PnPList -Identity "Shared Documents").ItemCount

Write-Host "Source Count: $SourceCount | Target Count: $TargetCount"
if ($SourceCount -eq $TargetCount) {
    Write-Host "๐ŸŽ‰ MIGRATION VERIFIED: Document counts match 100%!" -ForegroundColor Green
} else {
    Write-Host "⚠️ DISCREPANCY DETECTED: Source and Target counts differ by $($SourceCount - $TargetCount)" -ForegroundColor Red
}

๐Ÿ’ฌ Request a Custom SharePoint Script

Need a custom PnP PowerShell script, Graph API automation code, or SharePoint governance walkthrough? Submit your request below to LoveSharePoint Team.

No comments:

Post a Comment