Private/Resolve-TLObjectId.ps1
|
function Resolve-TLObjectId { <# .SYNOPSIS Resolves directory object GUIDs to display names via a session-wide cache. .DESCRIPTION Uses POST /directoryObjects/getByIds in chunks of 1000. Non-GUID values ('All', 'None', 'GuestsOrExternalUsers', ...) pass through unchanged. Returns a hashtable: id -> @{ DisplayName; Type }. #> [CmdletBinding()] param( [AllowEmptyCollection()] [AllowNull()] [string[]]$Id ) $result = @{} if (-not $Id -or @($Id).Count -eq 0) { return $result } $guidPattern = '^[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$' $toLookup = [System.Collections.Generic.List[string]]::new() foreach ($value in @($Id | Where-Object { $_ } | Sort-Object -Unique)) { if ($value -notmatch $guidPattern) { $result[$value] = @{ DisplayName = $value; Type = 'wellKnown' } continue } if ($script:TLResolverCache.ContainsKey($value)) { $result[$value] = $script:TLResolverCache[$value] continue } $toLookup.Add($value) } for ($offset = 0; $offset -lt $toLookup.Count; $offset += 1000) { $chunk = @($toLookup[$offset..([Math]::Min($offset + 999, $toLookup.Count - 1))]) $found = @() try { $found = @(Invoke-TLGraphRequest -Method POST -Uri '/v1.0/directoryObjects/getByIds' -Body @{ ids = @($chunk) } -All) } catch { Write-Verbose ("getByIds lookup failed for {0} ids: {1}" -f $chunk.Count, $_.Exception.Message) } foreach ($object in $found) { $entry = @{ DisplayName = [string]$object.displayName Type = ([string]$object.'@odata.type') -replace '^#microsoft\.graph\.', '' } $script:TLResolverCache[$object.id] = $entry $result[$object.id] = $entry } foreach ($miss in $chunk) { if (-not $result.ContainsKey($miss)) { # Deleted objects are not returned by getByIds - keep the id visible. $entry = @{ DisplayName = "unresolved ($miss)"; Type = 'unknown' } $script:TLResolverCache[$miss] = $entry $result[$miss] = $entry } } } return $result } |