Remove All Permissions in a SharePoint Site Collection


Sometimes a SharePoint site collection needs to be locked down to just you — before a migration, before deletion, or because everyone who had a reason to be in there no longer does. This covers both ways to strip every permission except your own: through the admin center by hand, or with PowerShell when you’re doing this across more than one site.


In this post: How permission inheritance affects this · Method 1: SharePoint Admin Center · Method 2: PowerShell · Scripting the broken-inheritance sweep too · Group-connected sites are a different case · Best practices · When would you actually use this? · Related reading


How permission inheritance affects this

By default, subsites, libraries, and lists inherit permissions from the site collection above them. Removing access at the top level cascades down automatically for anything still inheriting — but any list or library where inheritance was already broken has its own permission set and needs to be handled separately. A few things worth keeping straight before you start:

  • Check for broken inheritance first. Anything with unique permissions won’t be touched by a top-level change and needs its own pass.
  • Don’t remove your own access. It sounds obvious until you’re scripting a loop over every user and forget to exclude yourself.
  • Site Owners and Site Collection Administrators carry elevated rights that don’t always show up in a straightforward user list — account for them explicitly rather than assuming a general permissions sweep catches them.

Method 1: SharePoint Admin Center

Fine for a one-off, on a single site:

  1. Go to the Microsoft 365 Admin Center, then SharePoint under Admin centers.
  2. Under Active sites, find and select the site collection you’re locking down.
  3. Open Permissions, and remove every user and group except yourself — confirm you still hold Full Control before you finish.
  4. Check any list or library that has its own unique permissions (broken inheritance) and repeat the removal there — the top-level change won’t reach them.

Method 2: PowerShell

Worth it once you’re doing this across more than one site, or want it repeatable:

  • Install PnP PowerShell if you don’t already have it: Install-Module PnP.PowerShell -Force -AllowClobber
  • Connect to the site: Connect-PnPOnline -Url "https://yourtenant.sharepoint.com/sites/YourSite" -Interactive
# Connect to SharePoint site
$siteUrl = "https://yourtenant.sharepoint.com/sites/YourSite"
Connect-PnPOnline -Url $siteUrl -Interactive

# Get site administrators
$siteAdmins = Get-PnPSiteCollectionAdmin

# Get all users and groups
$users = Get-PnPUser

# Remove users except for site administrators
foreach ($user in $users) {
    if ($siteAdmins.LoginName -notcontains $user.LoginName) {
        Remove-PnPUser -Identity $user.LoginName
        Write-Host "Removed: $($user.LoginName)"
    }
}

# Remove SharePoint Groups except the Owners group
$groups = Get-PnPGroup
foreach ($group in $groups) {
    if ($group.Title -notmatch "Owners") {
        Remove-PnPGroup -Identity $group.Title
        Write-Host "Removed Group: $($group.Title)"
    }
}

Write-Host "All non-admin permissions removed successfully!"

Note the cmdlet is Remove-PnPUser, not Remove-PnPSiteUser — the latter doesn’t exist in current PnP PowerShell and will just error out if you go looking for it. After running the script, confirm the result under Site Settings > Site Permissions — only your account (and any necessary system accounts) should remain.


Scripting the broken-inheritance sweep too

The script above only reaches the site-collection level — exactly the gap flagged at the top of this post: any list or library where inheritance was already broken keeps its own separate permission set and needs its own pass. The cleanest fix for a full lockdown is resetting those back to inherited first, so the site-level cleanup above then actually covers them:

# Find every list/library with broken inheritance and reset it back to inherited
$lists = Get-PnPList | Where-Object { -not $_.Hidden }

foreach ($list in $lists) {
    if ($list.HasUniqueRoleAssignments) {
        Set-PnPList -Identity $list -ResetRoleInheritance
        Write-Host "Reset inheritance on: $($list.Title)"
    }
}

Run this before the user/group removal script above, not after — resetting inheritance first means every list and library is back to inheriting from the site collection by the time the top-level cleanup runs, so one pass actually reaches everything instead of leaving unique-permission scopes silently untouched. If a specific list needs to stay locked to a narrower audience even after the rest of the site is stripped, exclude it from this loop deliberately rather than resetting it and re-breaking it after.


Group-connected sites are a different case

Worth checking this before assuming the script above fully locked the site down: on a site connected to a Microsoft 365 Group (most modern Team Sites are), access flows from the Group’s own Owners/Members/Guests membership, not from the SharePoint site’s user list directly — `Remove-PnPUser` against the site strips a directly-added user, but a Group member still gets back in through their Group membership, since that’s a separate object entirely. For a genuine full lockdown on a Group-connected site, the Group membership itself needs clearing too:

# Clear Microsoft 365 Group membership too, for a Group-connected site
$groupId = (Get-PnPMicrosoft365Group -Identity "YourGroupName").Id
$members = Get-PnPMicrosoft365GroupMember -Identity $groupId

foreach ($member in $members) {
    Remove-PnPMicrosoft365GroupMember -Identity $groupId -Users $member.UserPrincipalName
    Write-Host "Removed from Group: $($member.UserPrincipalName)"
}

Worth checking which kind of site is actually being locked down before running either script alone — `Get-PnPSite -Includes GroupId` returns a populated `GroupId` for a Group-connected site (empty/null for a standalone site), which is the fast way to know whether the Group-membership step is even needed.


Best practices
  • Export the existing permission list before you touch anything. A quick Get-PnPUser/Get-PnPGroup dump to CSV gives you something to restore from if this needs reversing.
  • Test on a non-critical site first if you’re running the script for the first time, rather than pointing it straight at production.
  • Always keep at least one admin account. A stripped site with zero admins needs a Global Administrator to fix — avoidable with one line of caution.
  • Log what got removed. A permissions sweep is exactly the kind of change that needs an audit trail if anyone asks “who had access before this.”

Removing your own access by accident is the actual risk here — exclude yourself from the loop explicitly, don’t assume the script will figure it out.

When would you actually use this?
  • A site is being decommissioned and needs to sit locked down before deletion, so no one stumbles into stale content in the meantime.
  • External vendor or guest access needs to be revoked wholesale once a project wraps, while keeping the site itself for internal reference.
  • A site holding sensitive data needs to be restricted to a single owner (a compliance officer, an auditor) once its active collaboration phase is over.


Quick tip, but a useful one — comment below with questions.


App Catalog Authentication Automation Backup Compliance Content Type CSS Flows Google Javascript Limitations List Metadata MFA Microsoft Node NodeJs O365 OneDrive Permissions PnP PnPJS Policy PowerApps Power Automate PowerAutomate PowerPlatform PowerShell React ReactJs Rest API Rest Endpoint Security Send an HTTP Request to SharePoint SharePoint SharePoint List SharePoint Modern SharePoint Online SPFX SPO Sync Tags Teams Termstore Versioning

Leave a Comment

Your email address will not be published. Required fields are marked *