Private/26-GetAtlasConditionalAccessReference.ps1
|
function Get-AtlasConditionalAccessReference { [CmdletBinding()] param( [Parameter(Mandatory)] [string] $TenantId, [Parameter(Mandatory)] [AllowEmptyCollection()] [AtlasNode[]] $KnownNode ) $result = [AtlasCollectionResult]::new() $policyKeyById = @{} foreach ($node in $KnownNode | Where-Object Kind -eq 'conditionalAccessPolicy') { $policyKeyById[$node.Id] = $node.Key } $namedLocationsEndpoint = '/v1.0/identity/conditionalAccess/namedLocations' $authStrengthEndpoint = '/v1.0/policies/authenticationStrengthPolicies' $policiesEndpoint = '/v1.0/identity/conditionalAccess/policies' try { $namedLocationResponse = Invoke-AtlasGraphRequest -Uri $namedLocationsEndpoint } catch { $result.Status = 'partial' $result.Warnings.Add("Conditional Access named locations could not be collected: $(Get-AtlasSafeErrorDetail -ErrorRecord $_)") $namedLocationResponse = [pscustomobject] @{ Items = @() Metrics = @{ requestCount = 0; retryCount = 0 } } } try { $authStrengthResponse = Invoke-AtlasGraphRequest -Uri $authStrengthEndpoint } catch { $result.Status = 'partial' $result.Warnings.Add("Authentication strengths could not be collected: $(Get-AtlasSafeErrorDetail -ErrorRecord $_)") $authStrengthResponse = [pscustomobject] @{ Items = @() Metrics = @{ requestCount = 0; retryCount = 0 } } } try { $policyResponse = Invoke-AtlasGraphRequest -Uri $policiesEndpoint } catch { $result.Status = 'partial' $result.Warnings.Add("Conditional Access policy references could not be collected: $(Get-AtlasSafeErrorDetail -ErrorRecord $_)") $policyResponse = [pscustomobject] @{ Items = @() Metrics = @{ requestCount = 0; retryCount = 0 } } } $namedLocationKeyById = @{} foreach ($location in $namedLocationResponse.Items) { $locationId = Get-AtlasResponseProperty -InputObject $location -Name 'id' if (-not $locationId) { continue } $displayName = Get-AtlasResponseProperty -InputObject $location -Name 'displayName' if (-not $displayName) { $displayName = $locationId } $odataType = Get-AtlasResponseProperty -InputObject $location -Name '@odata.type' $node = New-AtlasNode -TenantId $TenantId -Id $locationId -Kind 'namedLocation' -DisplayName $displayName -Properties @{ odataType = $odataType createdDateTime = Get-AtlasResponseProperty -InputObject $location -Name 'createdDateTime' modifiedDateTime = Get-AtlasResponseProperty -InputObject $location -Name 'modifiedDateTime' isTrusted = Get-AtlasResponseProperty -InputObject $location -Name 'isTrusted' } -Source @{ provider = 'microsoftGraph' apiVersion = 'v1.0' odataType = $odataType resourcePath = "/identity/conditionalAccess/namedLocations/$locationId" collector = 'conditionalAccessReferences' } $result.Nodes.Add($node) $namedLocationKeyById[$locationId] = $node.Key } $authStrengthKeyById = @{} foreach ($strength in $authStrengthResponse.Items) { $strengthId = Get-AtlasResponseProperty -InputObject $strength -Name 'id' if (-not $strengthId) { continue } $displayName = Get-AtlasResponseProperty -InputObject $strength -Name 'displayName' if (-not $displayName) { $displayName = $strengthId } $node = New-AtlasNode -TenantId $TenantId -Id $strengthId -Kind 'authenticationStrength' -DisplayName $displayName -Properties @{ description = Get-AtlasResponseProperty -InputObject $strength -Name 'description' policyType = Get-AtlasResponseProperty -InputObject $strength -Name 'policyType' requirementsSatisfied = Get-AtlasResponseProperty -InputObject $strength -Name 'requirementsSatisfied' allowedCombinations = @(Get-AtlasResponseProperty -InputObject $strength -Name 'allowedCombinations') } -Source @{ provider = 'microsoftGraph' apiVersion = 'v1.0' odataType = '#microsoft.graph.authenticationStrengthPolicy' resourcePath = "/policies/authenticationStrengthPolicies/$strengthId" collector = 'conditionalAccessReferences' } $result.Nodes.Add($node) $authStrengthKeyById[$strengthId] = $node.Key } foreach ($policy in $policyResponse.Items) { $policyId = Get-AtlasResponseProperty -InputObject $policy -Name 'id' if (-not $policyId -or -not $policyKeyById.ContainsKey($policyId)) { continue } $policyKey = $policyKeyById[$policyId] $conditions = Get-AtlasResponseProperty -InputObject $policy -Name 'conditions' $locations = Get-AtlasResponseProperty -InputObject $conditions -Name 'locations' $grantControls = Get-AtlasResponseProperty -InputObject $policy -Name 'grantControls' $authenticationStrength = Get-AtlasResponseProperty -InputObject $grantControls -Name 'authenticationStrength' $authenticationStrengthId = Get-AtlasResponseProperty -InputObject $authenticationStrength -Name 'id' foreach ($locationSet in @( @{ Values = @(Get-AtlasConditionalAccessCollection -Object $locations -Name 'includeLocations'); Relationship = 'conditionalAccessIncludesLocation'; Assignment = 'include' } @{ Values = @(Get-AtlasConditionalAccessCollection -Object $locations -Name 'excludeLocations'); Relationship = 'conditionalAccessExcludesLocation'; Assignment = 'exclude' } )) { foreach ($locationId in $locationSet.Values) { if (-not $locationId -or $locationId -eq 'All' -or -not $namedLocationKeyById.ContainsKey($locationId)) { continue } $evidence = New-AtlasEvidence -TenantId $TenantId -Collector 'conditionalAccessReferences' -Endpoint $policiesEndpoint -SourceObjectId "$policyId|$($locationSet.Assignment)|location|$locationId" -Fields @{ policyId = $policyId locationId = $locationId assignment = $locationSet.Assignment } $result.Evidence.Add($evidence) $result.Edges.Add( (New-AtlasEdge -TenantId $TenantId -From $policyKey -To $namedLocationKeyById[$locationId] -Relationship $locationSet.Relationship -State @{ assignment = $locationSet.Assignment } -EvidenceIds @($evidence.Key) -Source @{ collector = 'conditionalAccessReferences' }) ) } } if ($authenticationStrengthId -and $authStrengthKeyById.ContainsKey($authenticationStrengthId)) { $evidence = New-AtlasEvidence -TenantId $TenantId -Collector 'conditionalAccessReferences' -Endpoint $policiesEndpoint -SourceObjectId "$policyId|authenticationStrength|$authenticationStrengthId" -Fields @{ policyId = $policyId authenticationStrengthId = $authenticationStrengthId } $result.Evidence.Add($evidence) $result.Edges.Add( (New-AtlasEdge -TenantId $TenantId -From $policyKey -To $authStrengthKeyById[$authenticationStrengthId] -Relationship 'requiresAuthenticationStrength' -State @{ authenticationStrengthId = $authenticationStrengthId } -EvidenceIds @($evidence.Key) -Source @{ collector = 'conditionalAccessReferences' }) ) } } $result.Metrics = @{ namedLocationCount = $namedLocationResponse.Items.Count authenticationStrengthCount = $authStrengthResponse.Items.Count referenceEdgeCount = $result.Edges.Count requestCount = $namedLocationResponse.Metrics.requestCount + $authStrengthResponse.Metrics.requestCount + $policyResponse.Metrics.requestCount retryCount = $namedLocationResponse.Metrics.retryCount + $authStrengthResponse.Metrics.retryCount + $policyResponse.Metrics.retryCount } return $result } |