Private/Get-SPCLibraryBrokenInheritanceInternal.ps1
|
function Get-SPCLibraryBrokenInheritanceInternal { [CmdletBinding()] [OutputType([PSCustomObject])] param ( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [string]$SiteUrl, [Parameter()] [switch]$AddTempSiteCollectionAdmin ) begin { Write-Verbose "Entering Get-SPCLibraryBrokenInheritanceInternal for Site: $SiteUrl" } process { $removeSca = $false $myUPN = $null $siteConn = $null try { Write-Verbose "Connecting to PnP Online for Site: $SiteUrl" $retryConnection = $true $attemptedSca = $false while ($retryConnection) { $retryConnection = $false try { $siteConn = Connect-SPCSiteInternal -SiteUrl $SiteUrl -Context $script:SPCContext $lists = Get-PnPList -Connection $siteConn -Includes HasUniqueRoleAssignments, RootFolder -ErrorAction Stop | Where-Object { $_.BaseType -eq 'DocumentLibrary' -and $_.Hidden -eq $false } } catch { $ex = $_.Exception if (($ex.Message -match "401|403|Access.*denied|Unauthorized|E_ACCESSDENIED|forbidden" -or $_.FullyQualifiedErrorId -match "401|403|Unauthorized|Access.*Denied") -and -not $attemptedSca) { $attemptedSca = $true if ($AddTempSiteCollectionAdmin) { $authMethod = if ($script:SPCContext.AuthMethod) { $script:SPCContext.AuthMethod } else { $script:SPCContext.AuthMode } if ($authMethod -ne 'Interactive') { Write-Error "[ERR-GBI-004] $(Get-Date -Format 'o'): Access Denied on '$SiteUrl'. -AddTempSiteCollectionAdmin is only supported for Interactive auth. Resource: $SiteUrl." -ErrorAction Continue return } Write-Verbose "Get-SPCLibraryBrokenInheritanceInternal: Access Denied on '$SiteUrl'. Attempting temporary elevation." $elevationRecord = Invoke-SPCTempElevationInternal -SiteUrl $SiteUrl -Context $script:SPCContext if ($elevationRecord.Success) { $retryConnection = $true continue } else { Write-Warning "[WARN-GBI-005] $(Get-Date -Format 'o'): Access Denied on '$SiteUrl'. Skipping restricted site. Details: $($elevationRecord.ErrorMessage)" return } } else { Write-Error "ERR-201: Access Denied fetching lists for site $SiteUrl. Details: $($ex.Message)" return } } else { Write-Error "ERR-201: Failed to fetch lists for site $SiteUrl. Details: $($_.Exception.Message)" return } } } if ($null -ne $lists) { foreach ($list in $lists) { try { if ($list.HasUniqueRoleAssignments) { [PSCustomObject]@{ Path = $list.RootFolder.ServerRelativeUrl Type = "Library" } } Write-Verbose "Fetching items for list: $($list.Title) using pagination" $retryCount = 0 $maxRetries = 5 $success = $false $items = $null while (-not $success -and $retryCount -lt $maxRetries) { try { $items = Get-PnPListItem -Connection $siteConn -List $list.Title -PageSize 500 -Includes HasUniqueRoleAssignments, FileSystemObjectType -ErrorAction Stop $success = $true } catch { if ($_.Exception.Message -match "429" -or $_.Exception.Message -match "Too Many Requests") { $retryCount++ $waitTime = [math]::Pow(2, $retryCount) Write-Verbose "Throttling... retrying in $waitTime seconds (Attempt $retryCount of $maxRetries)" Start-Sleep -Seconds $waitTime if ($retryCount -ge $maxRetries) { throw "Exceeded maximum retries for list $($list.Title) due to throttling." } } else { throw $_ } } } if ($items) { foreach ($item in $items) { if ($item.HasUniqueRoleAssignments) { $itemUrl = "" if ($item.FieldValues.ContainsKey('FileRef')) { $itemUrl = $item.FieldValues['FileRef'] } else { $itemUrl = "$($list.RootFolder.ServerRelativeUrl)/Item_$($item.Id)" } [PSCustomObject]@{ Path = $itemUrl Type = if ($item.FileSystemObjectType -eq 'Folder') { "Folder" } else { "File/Item" } } } } } } catch { Write-Error "ERR-202: Failed to process list $($list.Title) on site $SiteUrl. Details: $_" } } } } finally { if ($elevationRecord -and $elevationRecord.Success) { Undo-SPCTempElevationInternal -ElevationRecord $elevationRecord -SiteConnection $siteConn -Context $script:SPCContext } } } end { Write-Verbose "Completed Get-SPCLibraryBrokenInheritanceInternal for Site: $SiteUrl" } } |