7/08/2014

SharePoint PowerShell–Find all Broken Inheritance

The following applies to both SharePoint 2010 and SharePoint 2013 on premises, but not to Office 365.

One of the common SharePoint tasks when you need to do a security audit, document security or cleanup a farm before an upgrade, is to try to figure out where the Site Owners have broken inheritance and created unique permissions. You could visit every site, list, library, folder, list item and document, or you could let PowerShell do the work for you.

The following is one of the many scripts found in SharePoint® 2010 Security for the Site Owner and my PowerShell class "MS-55095 SharePoint 2010 and 2013 Auditing and Site Content Administration using PowerShell". (Sign up for the July class and get a free copy of the book!)
 

First find all of the Webs with broken inheritance:

Get-SPSite http://yourSiteUrl  | 
Get-SPWeb -Limit All | 
Where { $_.HasUniquePerm -AND $_.ParentWeb -NE $Null } | 
Select ServerRelativeUrl, {$_.ParentWeb.ServerRelativeUrl}

 

Then find all of the Lists and Libraries with broken inheritance:

Get-SPSite http://yourSiteUrl  | 
Get-SPWeb -Limit All | 
Select -ExpandProperty Lists |
Where { $_.HasUniqueRoleAssignments -AND -NOT $_.Hidden } | 
Select Title, ParentWebUrl

 

Then find all of the folders with broken inheritance:

Get-SPSite http://yourSiteUrl  | 
Get-SPWeb -Limit All | 
Select -ExpandProperty Lists | 
Select -ExpandProperty Folders | 
Where { $_.HasUniqueRoleAssignments } | 
Select Title, {$_.ParentList.ParentWebUrl + "/" +$_.ParentList.Title}

 

Then find all of the items with broken inheritance:

Get-SPSite http://yourSiteUrl  | 
Get-SPWeb -Limit All | 
Select -ExpandProperty Lists | 
Select -ExpandProperty Items | 
Where { $_.HasUniqueRoleAssignments } | 
Select Name, {$_.ParentList.ParentWebUrl + "/" +$_.ParentList.Title}

 

What if we wanted a nice single list as the output?

Each of the scripts above return different kinds of columns. As PowerShell is a bit picky about what it will merge into a single column we will have a little more work to merge everything into a single list. One solution is to build an array or collection in memory, but this could get quite large. Another solution is to dump everything in to a CSV file and then open the result in Excel.

Note: The following script uses Export-CSV with the –Append parameter, which is not available in PowerShell 2.0.

Changes to the script:

  • Add something to the Selects to identify the source.
      Select "List Item", Url, {$_.Web.Url}
  • Create custom columns so all of the results have the same column names.
  • Output the results to a CSV file.
      | Export-CSV "c:\test\BrokenInheritanceReport.csv" –Append
  • Read them back and apply any needed sorting.

The following is all one script!


$siteUrl = "http://urlToYourSite"
$savePath = "c:\test\BrokenInheritanceReport.csv"

Get-SPSite $siteUrl  | 
  Get-SPWeb -Limit All | 
  Where { $_.HasUniquePerm -AND $_.ParentWeb -NE $Null } | 
  Select @{Label="Securable"; Expression={"Web"}}, 
         @{Label="Item"; Expression={$_.ServerRelativeUrl}}, 
         @{Label="Parent"; Expression={$_.ParentWeb.ServerRelativeUrl}} |
  Export-CSV $savePath

Get-SPSite $siteUrl  | 
  Get-SPWeb -Limit All | 
  Select -ExpandProperty Lists | 
  Where { $_.HasUniqueRoleAssignments -AND -NOT $_.Hidden } | 
  Select @{Label="Securable"; Expression={"List"}}, 
         @{Label="Item"; Expression={$_.Title}}, 
         @{Label="Parent"; Expression={$_.ParentWebUrl}} |
  Export-CSV $savePath -Append

Get-SPSite $siteUrl  | 
  Get-SPWeb -Limit All | 
  Select -ExpandProperty Lists | 
  Where { -NOT $_.Hidden -AND $_.EntityTypeName -NE "PublishedFeedList" } | 
  Select -ExpandProperty Folders | 
  Where { $_.HasUniqueRoleAssignments } | 
  Select @{Label="Securable"; Expression={"Folder"}}, 
         @{Label="Item"; Expression={$_.Title}}, 
         @{Label="Parent"; Expression={$_.ParentList.ParentWebUrl + "/" +$_.ParentList.Title}} | 
  Export-CSV $savePath -Append

Get-SPSite $siteUrl  | 
  Get-SPWeb -Limit All | 
  Select -ExpandProperty Lists | 
  Where { -NOT $_.Hidden -AND $_.EntityTypeName -NE "PublishedFeedList" } | 
  Select -ExpandProperty Items | 
  Where { $_.HasUniqueRoleAssignments } | 
  Select @{Label="Securable"; Expression={"Item"}}, 
         @{Label="Item"; Expression={$_.Name}}, 
         @{Label="Parent"; Expression={$_.ParentList.ParentWebUrl + "/" +$_.ParentList.Title}} | 
  Export-CSV $savePath -Append


Import-CSV  $savePath | Sort Parent | Select *
# or open the CSV file in Excel and sort there.

3 comments:

Tim McInnes said...

Thanks Mike the script works perfect! If I wanted to see the AD groups and users that had unique permissions to these broken sites/groups/lists what code would I add to the script?

Mike Smith said...

Tim,

Take a look at an article I wrote for SharePoint Pro Magazine and see if it has what you need:
http://sharepointpromag.com/sharepoint-2013/exploring-sharepoint-users-groups-and-security-using-powershell

Mike

Unknown said...

Thanks Mike, had a look at that and saw there is a line that will look up users of a certain group but unfortunately I don't have much experience. Is there a way to integrate that into the script above? thanks

Note to spammers!

Spammers, don't waste your time... all posts are moderated. If your comment includes unrelated links, is advertising, or just pure spam, it will never be seen.