Forum Discussion
Fromelard
Oct 14, 2020Steel Contributor
SharePoint - How to Reset Inheritance Permission set into an SP DocLib folder or file
When we are importing File Server content into SharePoint using dedicated tools for, we can import permission set configured at the sub levels (subfolders or documents). That import can create some issues due to incorrect configuration in place on original File Server.
But how can we check one user complaining to not see or access the content as it was into the File Server ?
That need to be reviewed at any SharePoint Content Level with Permission Management with "Administrator Permission" with the link "Manage Access".
You have to select the link (at the bottom) "Advanced" to have the exact permission set configured at this level
Based on that situation, you can decide what to apply at this folder or file level. You can:
- add a colleague or a group with appropriate permission (Read, Write or full control)
- Remove the specific permission of that level clicking on "Delete unique permissions"
But this config could concern many other sublevels and wait the user complains is probably not the best option.
How to track folders or files with unique permissions ?
You can do that using the Document Library Permission Settings from:
- Library Settings > "Permissions for this Document Library"
You will have the permission configuration in place at this root Document library level.
But the first line will explain (if that is the case into your document library) the status of sublevel:
- Some items of this list may have unique permissions which are not controlled from this page. Show these items.
When you are clicking on that link it will show you a part of customized levels.
You can change the permission set for each of those level clicking on "Manage Permissions" to have the same details we look in the first part of this message.
Now as you can imagine with a document library could contains thousands of folders, this manual action is really huge.
How reset all customized permissions configured at sublevel ?
That is the best option you can select as site admin, using PowerShell and an interesting PS Module named:
This following script will help IT Team to reconfigure all content customized into the document library and cancel this and reconfigure permission inheritance instead.
#install-module SharePointPnPPowerShellOnline -Force #to install that module the first time only
Write-Host " ---------------------------------------------- "
Import-Module SharePointPnPPowerShellOnline
Write-Host " ---------------------------------------------- "
#Config Variables
$SiteURL = "https://yourtenant.sharepoint.com/sites/YourSiteCollection/"
$ListTitle = "Document Library Name"
$foldertoscope = "/sites/YourSiteCollection/YourDocumentLibrary/"
#Connect to PnP Online
Connect-PnPOnline -Url $SiteURL -UseWebLogin
$ctx = Get-PnPContext
$ctx.Load($ctx.Web.Lists)
$ctx.Load($ctx.Web)
$ctx.Load($ctx.Web.Webs)
$ctx.ExecuteQuery()
$ll=$ctx.Web.Lists.GetByTitle($ListTitle)
$ctx.Load($ll)
$ctx.ExecuteQuery()
## View XML
$qCommand = @"
<View Scope="RecursiveAll">
<Query>
<OrderBy><FieldRef Name='ID' Ascending='TRUE'/></OrderBy>
</Query>
<RowLimit Paged="TRUE">5000</RowLimit>
</View>
"@
## Page Position
$position = $null
## All Items
$allItems = @()
Do{
$camlQuery = New-Object Microsoft.SharePoint.Client.CamlQuery
$camlQuery.ListItemCollectionPosition = $position
$camlQuery.ViewXml = $qCommand
## Executing the query
$currentCollection = $ll.GetItems($camlQuery)
$ctx.Load($currentCollection)
$ctx.ExecuteQuery()
## Getting the position of the previous page
$position = $currentCollection.ListItemCollectionPosition
# Adding current collection to the allItems collection
$allItems += $currentCollection
Write-Host "Collecting items. Current number of items: " $allItems.Count
}
while($position -ne $null)
Write-Host "Total number of items: " $allItems.Count
for($j=0;$j -lt $allItems.Count ;$j++)
{
if($allItems[$j]["FileRef"].StartsWith($foldertoscope))
{
Write-Host "Resetting permissions for " $allItems[$j]["Title"] ".." $allItems[$j]["FileRef"]
$allItems[$j].ResetRoleInheritance()
$ctx.ExecuteQuery()
}
}
Now you can adapt the permissions as much as you need to
Fabrice Romelard
- bobitoCopper ContributorIf anyone has the issue where it returns the number of items found but doesn't reset the permissions, be sure you don't have any %20 in place of spaces. E.g. /sites/site%20name/shared%20documents/ should be entered as /sites/site name/shared documents/.
- sir_actionCopper Contributor
bobito
Two notes:
Running the script from Visual Studio code does not work.
I managed to get to the reset permissions phase: the content of the $foldertoscope is case sensitive. I recommend to check (print) the value of ($allItems[$j]["FileRef"] and use that to set the value of $foldertoscope
- DeclanTyndallCopper ContributorCan you explain what exactly the "IF" portion of the script is doing, similarly to others i was having trouble getting it to run past the discovery phase, i added the below else statement and it would spit out "Failed" the for each item it discovered so the for Loop was working fine. I commented out the "IF" statement and it worked so i think, at least for me, thats where the issue is.
if($allItems[$j]["FileRef"].StartsWith($foldertoscope))
{
Write-Host "Resetting permissions for " $allItems[$j]["Title"] ".." $allItems[$j]["FileRef"]
$allItems[$j].ResetRoleInheritance()
$ctx.ExecuteQuery()
}
else
{
write-host "Failed"
} - Justin_ReidCopper Contributor
- FromelardSteel ContributorYou are welcome 🙂
Fab
- MetsCaniacCopper ContributorI am having difficulty getting the script to finish. I need it to run on the this site which is the main team site created in a new M365 tenant.
https://<domain>.sharepoint.com/Shared%20Documents
however...when it runs, the collecting occurs but the resetting does not. I am guessing I do not have a variable correct. Do you have a suggestion?- OsmundoCopper ContributorI have the same issue with this script, it stops at item collection and never runs the actual resetting. Anybody found the solution?
- AdamDoddsCopper Contributor
I know you asked well over 6 months ago but if anyone else faces the same problem, here is how I fixed it
For a root SharePoint site it should be set out like this:
#Config Variables
$SiteURL = "https://company.sharepoint.com/"
$ListTitle = "Documents"$foldertoscope = "/Shared Documents/"
- roymaaloufCopper ContributorI run the script as below:
install-module SharePointPnPPowerShellOnline -Force #to install that module the first time only
#install-module SharePointPnPPowerShellOnline -Force #to install that module the first time only
Write-Host " ---------------------------------------------- "
Import-Module SharePointPnPPowerShellOnline
Write-Host " ---------------------------------------------- "
#Config Variables
$SiteURL = " https://medair.sharepoint.com/sites/GlobalITS/"
$ListTitle = "Documents"
$foldertoscope = "/sites/GlobalITS/Shared%20Documents/"
#Connect to PnP Online
Connect-PnPOnline -Url $SiteURL -UseWebLogin
$ctx = Get-PnPContext
$ctx.Load($ctx.Web.Lists)
$ctx.Load($ctx.Web)
$ctx.Load($ctx.Web.Webs)
$ctx.ExecuteQuery()
$ll=$ctx.Web.Lists.GetByTitle($ListTitle)
$ctx.Load($ll)
$ctx.ExecuteQuery()
## View XML
$qCommand = @"
<View Scope="RecursiveAll">
<Query>
<OrderBy><FieldRef Name='ID' Ascending='TRUE'/></OrderBy>
</Query>
<RowLimit Paged="TRUE">5000</RowLimit>
</View>
"@
## Page Position
$position = $null
## All Items
$allItems = @()
Do{
$camlQuery = New-Object Microsoft.SharePoint.Client.CamlQuery
$camlQuery.ListItemCollectionPosition = $position
$camlQuery.ViewXml = $qCommand
## Executing the query
$currentCollection = $ll.GetItems($camlQuery)
$ctx.Load($currentCollection)
$ctx.ExecuteQuery()
## Getting the position of the previous page
$position = $currentCollection.ListItemCollectionPosition
# Adding current collection to the allItems collection
$allItems += $currentCollection
Write-Host "Collecting items. Current number of items: " $allItems.Count
}
while($position -ne $null)
Write-Host "Total number of items: " $allItems.Count
for($j=0;$j -lt $allItems.Count ;$j++)
{
if($allItems[$j]["FileRef"].StartsWith($foldertoscope))
{
Write-Host "Resetting permissions for " $allItems[$j]["Title"] ".." $allItems[$j]["FileRef"]
$allItems[$j].ResetRoleInheritance()
$ctx.ExecuteQuery()
}
}
----------------------------------------------
WARNING: The names of some imported commands from the module 'SharePointPnPPowerShellOnline' include unapproved verbs t
hat might make them less discoverable. To find the commands with unapproved verbs, run the Import-Module command again
with the Verbose parameter. For a list of approved verbs, type Get-Verb.
----------------------------------------------
WARNING:
You are running the legacy version of PnP PowerShell.
This version will be archived soon which means that while staying available, no updates or fixes will be released.
Consider installing the newer prereleased cross-platform version of PnP PowerShell.
This version has numerous improvements and many more cmdlets available.
To install the new version:
Uninstall-Module -Name SharePointPnPPowerShellOnline -AllVersions -Force
Install-Module -Name PnP.PowerShell
Read more about the new cross-platform version of PnP PowerShell at
https://pnp.github.io/powershell
To hide this message set the environment variable PNPLEGACYMESSAGE to "false"
In PowerShell add $env:PNPLEGACYMESSAGE='false' to your profile. Alternatively use 'Connect-PnPOnline -Url [yoururl] -W
arningAction Ignore'
Cannot convert argument "query", with value: "Microsoft.SharePoint.Client.CamlQuery", for "GetItems" to type
"Microsoft.SharePoint.Client.CamlQuery": "Cannot convert the "Microsoft.SharePoint.Client.CamlQuery" value of type
"Microsoft.SharePoint.Client.CamlQuery" to type "Microsoft.SharePoint.Client.CamlQuery"."
At line:45 char:5
+ $currentCollection = $ll.GetItems($camlQuery)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
Cannot find an overload for "Load" and the argument count: "1".
At line:46 char:5
+ $ctx.Load($currentCollection)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodCountCouldNotFindBest
Collecting items. Current number of items: 1
Total number of items: 1
Cannot index into a null array.
At line:63 char:8
+ if($allItems[$j]["FileRef"].StartsWith($foldertoscope))
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
I got the following result:- NickV2114Copper ContributorException calling "ExecuteQuery" with "0" argument(s): "The remote server returned an error: (400) Bad Request."
At line:66 char:9
+ $ctx.ExecuteQuery()
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : WebException
We get this error - is this Microsoft Throttling our connection?
- AD-CG-CAF-2018775Copper Contributor
Fromelard Thanks. I am trying to reset permissions for a specific folder within a library. I have gotten the script to run, but it just returns the amount of items it found in the whole document library not just that specific folder. It also does not go into the next step of resetting the permissions. Any advice would be much appreciated.
- aprietoCopper ContributorThis is working wonders for me, thanks, I just wonder if you are able to look at just folders within a Document Library?
Thanks- CFox-MeritCopper Contributor
aprietoYes, you can apply this just to a subfolder within a library. I found this site looking to do just that. You just need to set the "$foldertoscope =" parameter to the relative URL of the folder. The final loop of the script compares the path of every object to that string, and if it starts with that string, it resets the permissions.
- aprietoCopper ContributorCFox-Merit
Thanks for that Ive done that, but it still seems to be counting the whole Library, not sure what im doing wrong, im using "/sites/sitename/library/folder/ the one I'm testing on only had around 50 files and folders and this counts 5000 starting but goes up so cancel it, only because last time i ran at library it stated error because of the amount of requests
- FromelardSteel Contributor