|
| 1 | +function Set-CIPPDBCacheOneDriveRootPermissions { |
| 2 | + <# |
| 3 | + .SYNOPSIS |
| 4 | + Caches OneDrive root permissions for every personal site in a tenant. |
| 5 | +
|
| 6 | + .DESCRIPTION |
| 7 | + Self-contained cache writer: enumerates personal sites via paginated Graph getAllSites, |
| 8 | + fans out batched collection activities (20 sites each), and aggregates results in |
| 9 | + Push-StoreOneDriveRootPermissions (PostExecution). |
| 10 | +
|
| 11 | + One row per OneDrive site in OneDriveRootPermissions with permissionsJson (compressed grant |
| 12 | + array string), nullable hasNonStandardAccess, and collectionStatus (Full | Skipped). |
| 13 | +
|
| 14 | + Does not read OneDriveUsage or other CIPPDB caches. Requires SharePoint/OneDrive license |
| 15 | + (Test-CIPPStandardLicense -Preset SharePoint); unlicensed tenants exit before enumeration. |
| 16 | + Scheduling via CIPPDBCacheTypes.json is deferred — manual test: |
| 17 | + Invoke-ExecCIPPDBCache?TenantFilter={tenant}&Name=OneDriveRootPermissions |
| 18 | +
|
| 19 | + Site enumeration dedupes getAllSites results by siteId before batching. Empty tenants write |
| 20 | + an empty cache directly (PostExecution is skipped when there are zero batches). |
| 21 | +
|
| 22 | + PostExecution passes ExpectedSiteCount; Push-StoreOneDriveRootPermissions throws without writing |
| 23 | + if flattened row count does not match (prevents partial replace-mode wipe). Skipped site rows |
| 24 | + are merged with prior Full cache data when available (merge-on-Skip) so transient failures |
| 25 | + do not overwrite good grant data. |
| 26 | +
|
| 27 | + Owner resolution uses drive.owner (not Owners group or OneDriveUsage). permissionsJson grant |
| 28 | + paths: SiteAdmin, SiteRoleGroup, WebRoleAssignment, LibraryRoleAssignment, DriveRootGrant, |
| 29 | + DriveRootLink. Groups are stored as principals without Entra expansion. |
| 30 | +
|
| 31 | + Consumer limitations: grant paths != effective access; unprovisioned OneDrives absent; |
| 32 | + Skipped sites without a prior Full row have empty permissionsJson; merge-on-Skip may |
| 33 | + restore prior Full data after transient failures; count DriveRootLink entries by distinct |
| 34 | + permissionId (named recipients produce multiple grant rows per link); child folder/file |
| 35 | + sharing is out of scope (SharePointSharingLinks cache). |
| 36 | +
|
| 37 | + .PARAMETER TenantFilter |
| 38 | + Tenant to cache OneDrive root permissions for |
| 39 | +
|
| 40 | + .PARAMETER QueueId |
| 41 | + Optional queue ID for progress tracking |
| 42 | + #> |
| 43 | + [CmdletBinding()] |
| 44 | + param( |
| 45 | + [Parameter(Mandatory = $true)] |
| 46 | + [string]$TenantFilter, |
| 47 | + [string]$QueueId |
| 48 | + ) |
| 49 | + |
| 50 | + $BatchSize = 20 |
| 51 | + |
| 52 | + try { |
| 53 | + $LicenseCheck = Test-CIPPStandardLicense -StandardName 'OneDriveRootPermissionsCache' -TenantFilter $TenantFilter -Preset SharePoint -SkipLog |
| 54 | + if ($LicenseCheck -eq $false) { |
| 55 | + Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message 'Tenant does not have SharePoint/OneDrive license, skipping OneDrive root permissions cache' -sev Debug |
| 56 | + return |
| 57 | + } |
| 58 | + |
| 59 | + Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message 'Starting OneDrive root permissions collection' -sev Debug |
| 60 | + |
| 61 | + $RawSites = @(New-GraphGetRequest -uri "https://graph.microsoft.com/v1.0/sites/getAllSites?`$filter=isPersonalSite eq true&`$select=id,webUrl,displayName" -tenantid $TenantFilter -asapp $true) |
| 62 | + |
| 63 | + $SiteById = @{} |
| 64 | + foreach ($Site in $RawSites) { |
| 65 | + if ($Site.id) { $SiteById[$Site.id] = $Site } |
| 66 | + } |
| 67 | + $Sites = @($SiteById.Values) |
| 68 | + $ExpectedSiteCount = $Sites.Count |
| 69 | + |
| 70 | + if ($ExpectedSiteCount -eq 0) { |
| 71 | + Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message 'No personal sites found; writing empty OneDriveRootPermissions cache' -sev Debug |
| 72 | + Add-CIPPDbItem -TenantFilter $TenantFilter -Type 'OneDriveRootPermissions' -Data @() -AddCount |
| 73 | + return |
| 74 | + } |
| 75 | + |
| 76 | + $Batches = [System.Collections.Generic.List[object]]::new() |
| 77 | + $TotalBatches = [Math]::Ceiling($Sites.Count / $BatchSize) |
| 78 | + for ($i = 0; $i -lt $Sites.Count; $i += $BatchSize) { |
| 79 | + $BatchSites = $Sites[$i..[Math]::Min($i + $BatchSize - 1, $Sites.Count - 1)] |
| 80 | + $BatchNumber = [Math]::Floor($i / $BatchSize) + 1 |
| 81 | + $SiteSeeds = foreach ($Site in $BatchSites) { |
| 82 | + [PSCustomObject]@{ |
| 83 | + id = $Site.id |
| 84 | + webUrl = $Site.webUrl |
| 85 | + displayName = $Site.displayName |
| 86 | + } |
| 87 | + } |
| 88 | + $BatchItem = [PSCustomObject]@{ |
| 89 | + FunctionName = 'DBCacheOneDriveRootPermissionsBatch' |
| 90 | + TenantFilter = $TenantFilter |
| 91 | + QueueName = "OneDrive Root Permissions Batch $BatchNumber/$TotalBatches - $TenantFilter" |
| 92 | + BatchNumber = $BatchNumber |
| 93 | + TotalBatches = $TotalBatches |
| 94 | + Sites = @($SiteSeeds) |
| 95 | + } |
| 96 | + if ($QueueId) { |
| 97 | + $BatchItem | Add-Member -NotePropertyName 'QueueId' -NotePropertyValue $QueueId -Force |
| 98 | + } |
| 99 | + [void]$Batches.Add($BatchItem) |
| 100 | + } |
| 101 | + |
| 102 | + if ($QueueId -and $Batches.Count -gt 0) { |
| 103 | + try { |
| 104 | + Update-CippQueueEntry -RowKey $QueueId -TotalTasks $Batches.Count -IncrementTotalTasks |
| 105 | + } catch { |
| 106 | + Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "Could not update queue $QueueId with OneDrive root permission batch tasks: $($_.Exception.Message)" -sev Warning |
| 107 | + } |
| 108 | + } |
| 109 | + |
| 110 | + $InputObject = [PSCustomObject]@{ |
| 111 | + Batch = @($Batches) |
| 112 | + OrchestratorName = "OneDriveRootPermissions_$TenantFilter" |
| 113 | + PostExecution = @{ |
| 114 | + FunctionName = 'StoreOneDriveRootPermissions' |
| 115 | + Parameters = @{ |
| 116 | + TenantFilter = $TenantFilter |
| 117 | + ExpectedSiteCount = $ExpectedSiteCount |
| 118 | + } |
| 119 | + } |
| 120 | + } |
| 121 | + |
| 122 | + $null = Start-CIPPOrchestrator -InputObject $InputObject |
| 123 | + Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "Started OneDrive root permissions collection across $ExpectedSiteCount sites in $($Batches.Count) batches" -sev Debug |
| 124 | + |
| 125 | + } catch { |
| 126 | + Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "Failed to start OneDrive root permissions collection: $($_.Exception.Message)" -sev Error -LogData (Get-CippException -Exception $_) |
| 127 | + throw |
| 128 | + } |
| 129 | +} |
0 commit comments