Private/Resolve-ArgusSiteUrl.ps1
|
function Resolve-ArgusSiteUrl { <# .SYNOPSIS Returns the web URL of SharePoint sites from their Site Id (usage report rows with an empty Site URL). .DESCRIPTION The SharePoint usage reports can return an empty "Site URL" (Microsoft advisory SP676147); the documented workaround is to read the site from its "Site Id". When the PnP tenant site list (SharePointSites data set) is passed with -TenantSite, the URL is read from it first: it lists every site collection, including private group and channel sites that a delegated Graph call cannot read when the account is not a member of them. The remaining sites are read with one read-only GET /sites/{id}?$select=webUrl per site through JSON batching (Sites.Read.All). Returns a hashtable: lowercase Site Id -> webUrl. Sites that cannot be read are left out. #> [CmdletBinding()] [OutputType([hashtable])] param( [Parameter(Mandatory)] [AllowEmptyCollection()] [string[]] $SiteId, [AllowNull()] [object[]] $TenantSite ) $ids = @($SiteId | Where-Object { $_ -and $_ -ne [guid]::Empty.ToString() } | ForEach-Object { $_.ToLowerInvariant() } | Sort-Object -Unique) $result = @{} if ($ids.Count -eq 0) { return $result } foreach ($site in @($TenantSite | Where-Object { $_ })) { $id = ([string](Get-ArgusProperty $site 'SiteId' '')).ToLowerInvariant() $url = [string](Get-ArgusProperty $site 'Url' '') if ($id -and $url -and $id -in $ids) { $result[$id] = $url } } $requests = @($ids | Where-Object { -not $result.ContainsKey($_) } | ForEach-Object { @{ Id = $_; Url = "/sites/$_`?`$select=webUrl" } }) if ($requests.Count -eq 0) { return $result } foreach ($response in @(Invoke-ArgusGraphBatch -Request $requests)) { $url = if ($response.Status -eq 200) { [string](Get-ArgusProperty $response.Body 'webUrl' '') } else { '' } if ($url) { $result[[string]$response.Id] = $url } } $result } |