Private/20-GetAtlasUsers.ps1
|
function Get-AtlasUser { [CmdletBinding()] param( [Parameter(Mandatory)] [string] $TenantId ) $result = [AtlasCollectionResult]::new() $endpoint = '/v1.0/users?$select=id,displayName,userPrincipalName,userType,accountEnabled,department,jobTitle,companyName,country,city,officeLocation&$expand=manager($select=id,displayName)' $response = Invoke-AtlasGraphRequest -Uri $endpoint foreach ($user in $response.Items) { $properties = @{ userPrincipalName = $user.userPrincipalName userType = $user.userType accountEnabled = $user.accountEnabled } foreach ($attribute in @('department', 'jobTitle', 'companyName', 'country', 'city', 'officeLocation')) { $hasAttribute = if ($user -is [System.Collections.IDictionary]) { $user.Contains($attribute) } else { $null -ne $user.PSObject.Properties[$attribute] } if ($hasAttribute) { $properties[$attribute] = Get-AtlasResponseProperty -InputObject $user -Name $attribute } } $kind = if ($user.userType -eq 'Guest') { 'guestUser' } else { 'user' } $manager = Get-AtlasResponseProperty -InputObject $user -Name 'manager' $properties.managerId = Get-AtlasResponseProperty -InputObject $manager -Name 'id' $properties.managerDisplayName = Get-AtlasResponseProperty -InputObject $manager -Name 'displayName' $properties.managerCollectionStatus = if ($null -ne $user.PSObject.Properties['manager'] -or ($user -is [System.Collections.IDictionary] -and $user.Contains('manager'))) { 'collected' } else { 'unknown' } $node = New-AtlasNode -TenantId $TenantId -Id $user.id -Kind $kind -DisplayName $user.displayName -Properties $properties -Source @{ provider = 'microsoftGraph' apiVersion = 'v1.0' odataType = '#microsoft.graph.user' resourcePath = "/users/$($user.id)" collector = 'users' } $result.Nodes.Add($node) } # Graph can omit a null expanded manager. Resolve omissions with explicit GETs; # a denied request must not become a missing-manager finding. $unknownManagers = @($result.Nodes | Where-Object { $_.Properties.managerCollectionStatus -eq 'unknown' }) if ($unknownManagers.Count -gt 0) { $managerNodes = @{} $managerRequests = @(for ($index = 0; $index -lt $unknownManagers.Count; $index++) { $requestId = "manager-$index" $managerNodes[$requestId] = $unknownManagers[$index] [pscustomobject] @{ Id = $requestId; Uri = "/v1.0/users/$($unknownManagers[$index].Id)/manager?`$select=id,displayName" } }) try { $managerBatch = Invoke-AtlasGraphBatchGet -Request $managerRequests -BatchSize 10 -ProgressStatus 'User manager metadata' $response.Metrics.requestCount += $managerBatch.Metrics.requestCount $response.Metrics.retryCount += $managerBatch.Metrics.retryCount foreach ($managerResponse in $managerBatch.Responses) { $managerNode = $managerNodes[$managerResponse.Id] $managerNode.Properties.managerRequestStatus = $managerResponse.StatusCode if ($managerResponse.StatusCode -eq 404) { $managerNode.Properties.managerCollectionStatus = 'collected' } elseif ($managerResponse.StatusCode -eq 200 -and @($managerResponse.Items).Count -eq 1) { $managerNode.Properties.managerId = Get-AtlasResponseProperty -InputObject $managerResponse.Items[0] -Name id $managerNode.Properties.managerDisplayName = Get-AtlasResponseProperty -InputObject $managerResponse.Items[0] -Name displayName if ($managerNode.Properties.managerId) { $managerNode.Properties.managerCollectionStatus = 'collected' } } if ($managerNode.Properties.managerCollectionStatus -ne 'collected') { $result.Status = 'partial' $result.Warnings.Add("Manager metadata is unknown for user '$($managerNode.DisplayName)'.") } } } catch { $result.Status = 'partial' $result.Warnings.Add("Manager metadata collection failed: $(Get-AtlasSafeErrorDetail -ErrorRecord $_)") } } $result.Metrics = $response.Metrics return $result } |