Restoring and removing item permissions in subfolders for SharePoint Online using Powershell

This article describes a function of a custom SharePoint Online module available for download and installation from Github.

Prerequisites

  1. Download and install SharePoint Online SDK.
  2. Download and import module SPOMod using Import-Module PathToModule   cmdlet.
  • you can verify if the module has been imported by running Get-Module cmdlet

3. Run Connect-SPOCSOM cmdlet. 

Get folders and subfolders

This part assumes you are already connected to the right site. If you run Get-SPOList you see the list or library where you want to change permissions. In the examples we are using OneDrive for Business site, but the cmdlets work just as well for any other SharePoint site.

  1. Run 
Get-SPOListItems -ListTitle TheListWhereYouWantToChangePermissions

The cmdlet will not change any permissions. It will simply retrieve all list items, their titles, and IDs.
It will also display only the first level of files/folders.

But you probably have a nested structure and wanted to see all the items. That's what recursion is for. 

Get-SPOListItems -ListTitle TheListWhereYouWantToChangePermissions  -Recursive

Recursive is a switch parameter and does not need a value like $true to be enabled.

Next thing, you want to see more than IDs's numbers and titles that are often empty.
Get-SPOListItems -ListTitle TheListWhereYouWantToChangePermissions  -Recursive  -IncludeAllProperties $true
 
This should land us with a list view for each item similar to:

If you want to see only folders, you can use FsObjType property:

Get-SPOListItems -ListTitle Documents -Recursive -IncludeAllProperties $true | select fileleafref, fsobjtype | sort fsobjtype -Descending

As you can see folders have the value of FsObjType=1.
So let's choose only folders and their property that will be very helpful to us: relative URL hidden under the name of FileRef:

Get-SPOListItems -ListTitle Documents -Recursive -IncludeAllProperties $true | where {$_.FsObjType -eq 1} | select fileleafref, fileref

Get items from a subfolder

For that you will need one of the paths from the cmdlet above. You list items that are under this path. That includes not only items directly in this folder, but also its subfolders, sub-subfolders and items within them.

Get-SPOListItems -ListTitle Documents -Recursive -IncludeAllProperties $true | where {$_.FileRef -match"/personal/t_trial876_onmicrosoft_com/Documents/folder 1/folder 14"} | select fileleafref, fileref

Notice the difference in results between "/personal/t_trial876_onmicrosoft_com/Documents/folder 1/folder 14" and"/personal/t_trial876_onmicrosoft_com/Documents/folder 1/folder 14/"  ("/" at the end). The first will give you also the folder itself, the second only items below it.

Set permissions to unique

Save the items from a subfolder to a variable.

$SubfolderItems=(Get-SPOListItems -ListTitle Documents -Recursive -IncludeAllProperties $true | where {$_.FileRef -match"/personal/t_trial876_onmicrosoft_com/Documents/folder 1/folder 14/"} )

Loop through them setting their permissions to unique (stop inheriting from parent) with cmdlet Remove-SPOListItemInheritance. In this case the cmdlet with parameter KeepPermissions set to $false removes existing assigned permissions. It means that users who had permissions will lose them.  

foreach($item in $SubfolderItems){Remove-SPOListItemInheritance -ListTitle Documents -ItemID $item.ID -KeepPermissions $false}

Verify results

You can quickly check results for multiple items, by navigating to Site Settings>Site permissions. On the yellow ribbon you will see:
Some content on this site has different permissions from what you see here.  Show these items.  Click on Show these items:

Dialog box will appear with the name of your library. In my case, since I am operating on OneDrive for Business, it is "Documents". Click on "Manage permissions" next to the library name.

Settings for library permissions appear. Again you can see
Some content on this site has different permissions from what you see here.  Show these items.  Click on Show these items:

In the list that appears you should see all the items from your subfolder:

Restore permission inheritance

Save the items from a subfolder to a variable.

$SubfolderItems=(Get-SPOListItems -ListTitle Documents -Recursive -IncludeAllProperties $true | where {$_.FileRef -match"/personal/t_trial876_onmicrosoft_com/Documents/folder 1/folder 14/"} )

Loop through them, restoring permissions inherited from the parent element.

foreach($item in $SubfolderItems){Restore-SPOListItemInheritance -ListTitle Documents -ItemID $item.ID}

Verify results

You can quickly check results for multiple items, by navigating to Site Settings>Site permissions. On the yellow ribbon you will see:
Some content on this site has different permissions from what you see here.  Show these items.  Click on Show these items:

Dialog box will appear with the name of your library. In my case, since I am operating on OneDrive for Business, it is "Documents". Click on "Manage permissions" next to the library name.

Settings for library permissions appear. Again you can see
Some content on this site has different permissions from what you see here.  Show these items.  Click on Show these items:

The list should NOT show the items that you just restored inheritance for.

Break inheritance only for subfolders

Imagine that your structure looks like this and you would like to break inheritance for all A2x folders, e.g. A2x folders include material course for classes and each class (a,b,c) should have access only to their own material.
 

That means that all items inside the folder should be inheriting permissions from the their parent (e.g. Folder A2x a), but every folder should have broken permission inheritance.

Task 1

The goals for this task are:

  • stop inheriting permissions for folders: Folder A2x a, Folder A2x b, Folder A2x c, etc.
  • keep inheriting permissions for all items and subfolders inside Folder A2x a
  1.  Save the path to parent folder, i.e. Folder A2x. Make sure the path ends with "/". 
$pathToParentFolder="/personal/t_trial876_onmicrosoft_com/Documents/Folder A/Folder A2/A2x/"
  1. Get all folders under A2x folder:
Get-SPOListItems -ListTitle Documents -IncludeAllProperties $true -Recursive | where {$_.fileref -match $pathToParentFolder  -and  (($_.fileref.Replace($pathToParentFolder,"")) -notmatch "/" )} | select fileref
  1. Save them into variable:
$subfolders=(Get-SPOListItems -ListTitle Documents -IncludeAllProperties $true -Recursive | where {$_.fileref -match $pathToParentFolder -and (($_.fileref.Replace($pathToParentFolder,"")) -notmatch "/" )} )
  1. Loop through the items, removing their permissions. KeepPermissions $false will remove existing permissions. 
foreach($subfolder in $subfolders){Remove-SPOListItemInheritance -ListTitle Documents -ItemID $s
ubfolder.ID -KeepPermissions $false}
  1. Done :)

Task 2

Assume that in folder A2x there are files that are common for all courses. The files should stay with inherited permissions, the folders should have unique permissions. Subfolders should still inherit permissions from their parent folder, e.g. subfolder Abecadlo A2x a should inherit permissions from Folder A2x a.

Goals

The goals for this task are:

  • remove permission inheritance for folders: Folder A2x a, Folder A2x b, etc.
  • do not alter permissions for items inside the folders, e.g. Item A should still be inheriting permissions
  • do not alter permissions for files inside Folder A2x, e.g. Common material.pdf should still be inheriting permissions  

Steps

  1.  Save the path to the parent folder, i.e. Folder A2x. Make sure the path ends with "/". 
$pathToParentFolder="/personal/t_trial876_onmicrosoft_com/Documents/Folder A/Folder A2/A2x/"

  1.  Get all the items from Folder A2x, which are folders.
Get-SPOListItems -ListTitle Documents -IncludeAllProperties $true -Recursive | where {$_.fileref -match $pathToParentFolder  -and  (($_.fileref.Replace($pathToParentFolder,"")) -notmatch "/" ) -and ($_.FSObjType -eq 1)} | select fileref

where
$_``.fileref -match ``$pathToParentFolder   ``- chooses all items under A2x folder.
(``$_``.fileref.Replace(``$pathToParentFolder``,``""``)) -notmatch ``"/"    - eliminates all items in subfolders
$_``.FSObjType -eq 1                      - chooses only folders

  1. Save them into a variable.
$subfoldersOnly=(Get-SPOListItems -ListTitle Documents -IncludeAllProperties $true -Recursive | where {$_.fileref -match $pathToParentFolder  -and  (($_.fileref.Replace($pathToParentFolder,"")) -notmatch "/" ) -and ($_.FSObjType -eq 1)} )
  1. Remove their permissions.
foreach($subfolder in $subfoldersOnly){Remove-SPOListItemInheritance -ListTitle Documents -ItemID $subfolder.ID -KeepPermissions $false}

Downloads


Manage SharePoint Online Access Requests using Powershell
Working with multiple items using Powershell
SPOMod Cmdlets and Resources
SPOMod on GitHub