Private/27-GetAtlasExtendedPolicies.ps1
|
function Get-AtlasCrossTenantAccess { [CmdletBinding()] param( [Parameter(Mandatory)] [string] $TenantId ) $result = [AtlasCollectionResult]::new() $defaultEndpoint = '/v1.0/policies/crossTenantAccessPolicy/default' $partnersEndpoint = '/v1.0/policies/crossTenantAccessPolicy/partners?$expand=identitySynchronization' $defaultResponse = Invoke-AtlasGraphRequest -Uri $defaultEndpoint $defaultPolicy = @($defaultResponse.Items)[0] if ($null -eq $defaultPolicy) { $result.Status = 'partial' $result.Warnings.Add('The default cross-tenant access policy returned no data.') return $result } $defaultNode = New-AtlasNode -TenantId $TenantId -Id 'crossTenantAccessPolicy:default' -Kind 'crossTenantAccessPolicy' -DisplayName 'Default cross-tenant access settings' -Properties @{ b2bCollaborationInbound = Get-AtlasResponseProperty -InputObject $defaultPolicy -Name 'b2bCollaborationInbound' b2bCollaborationOutbound = Get-AtlasResponseProperty -InputObject $defaultPolicy -Name 'b2bCollaborationOutbound' b2bDirectConnectInbound = Get-AtlasResponseProperty -InputObject $defaultPolicy -Name 'b2bDirectConnectInbound' b2bDirectConnectOutbound = Get-AtlasResponseProperty -InputObject $defaultPolicy -Name 'b2bDirectConnectOutbound' inboundTrust = Get-AtlasResponseProperty -InputObject $defaultPolicy -Name 'inboundTrust' automaticUserConsentSettings = Get-AtlasResponseProperty -InputObject $defaultPolicy -Name 'automaticUserConsentSettings' tenantRestrictions = Get-AtlasResponseProperty -InputObject $defaultPolicy -Name 'tenantRestrictions' } -Source @{ provider = 'microsoftGraph' apiVersion = 'v1.0' odataType = '#microsoft.graph.crossTenantAccessPolicyConfigurationDefault' resourcePath = '/policies/crossTenantAccessPolicy/default' collector = 'crossTenantAccess' } -Tags @('externalAccess', 'policy') $result.Nodes.Add($defaultNode) $defaultEvidence = New-AtlasEvidence -TenantId $TenantId -Collector 'crossTenantAccess' -Endpoint $defaultEndpoint -SourceObjectId 'default' -Fields @{ policyType = 'default' settings = $defaultNode.Properties } $result.Evidence.Add($defaultEvidence) try { $partnerResponse = Invoke-AtlasGraphRequest -Uri $partnersEndpoint } catch { $result.Status = 'partial' $result.Warnings.Add("Cross-tenant partner settings could not be collected: $(Get-AtlasSafeErrorDetail -ErrorRecord $_)") $partnerResponse = [pscustomobject] @{ Items = @() Metrics = @{ requestCount = 0; retryCount = 0 } } } foreach ($partner in $partnerResponse.Items) { $partnerTenantId = Get-AtlasResponseProperty -InputObject $partner -Name 'tenantId' if (-not $partnerTenantId) { $partnerTenantId = Get-AtlasResponseProperty -InputObject $partner -Name 'id' } if (-not $partnerTenantId) { $result.Status = 'partial' $result.Warnings.Add('A cross-tenant partner configuration without a tenant ID was skipped.') continue } $identitySynchronization = Get-AtlasResponseProperty -InputObject $partner -Name 'identitySynchronization' $partnerDisplayName = Get-AtlasResponseProperty -InputObject $identitySynchronization -Name 'displayName' if (-not $partnerDisplayName) { $partnerDisplayName = "External tenant $partnerTenantId" } $partnerNode = New-AtlasNode -TenantId $TenantId -Id "externalTenant:$partnerTenantId" -Kind 'externalTenant' -DisplayName $partnerDisplayName -Properties @{ externalTenantId = $partnerTenantId isServiceProvider = Get-AtlasResponseProperty -InputObject $partner -Name 'isServiceProvider' b2bCollaborationInbound = Get-AtlasResponseProperty -InputObject $partner -Name 'b2bCollaborationInbound' b2bCollaborationOutbound = Get-AtlasResponseProperty -InputObject $partner -Name 'b2bCollaborationOutbound' b2bDirectConnectInbound = Get-AtlasResponseProperty -InputObject $partner -Name 'b2bDirectConnectInbound' b2bDirectConnectOutbound = Get-AtlasResponseProperty -InputObject $partner -Name 'b2bDirectConnectOutbound' inboundTrust = Get-AtlasResponseProperty -InputObject $partner -Name 'inboundTrust' automaticUserConsentSettings = Get-AtlasResponseProperty -InputObject $partner -Name 'automaticUserConsentSettings' tenantRestrictions = Get-AtlasResponseProperty -InputObject $partner -Name 'tenantRestrictions' identitySynchronization = $identitySynchronization } -Source @{ provider = 'microsoftGraph' apiVersion = 'v1.0' odataType = '#microsoft.graph.crossTenantAccessPolicyConfigurationPartner' resourcePath = "/policies/crossTenantAccessPolicy/partners/$partnerTenantId" collector = 'crossTenantAccess' } -Tags @('externalAccess', 'partnerTenant') $result.Nodes.Add($partnerNode) $evidence = New-AtlasEvidence -TenantId $TenantId -Collector 'crossTenantAccess' -Endpoint $partnersEndpoint -SourceObjectId $partnerTenantId -Fields @{ partnerTenantId = $partnerTenantId settings = $partnerNode.Properties } $result.Evidence.Add($evidence) $result.Edges.Add( (New-AtlasEdge -TenantId $TenantId -From $defaultNode.Key -To $partnerNode.Key -Relationship 'hasCrossTenantPartner' -State @{ partnerTenantId = $partnerTenantId userSyncInboundAllowed = Get-AtlasResponseProperty -InputObject (Get-AtlasResponseProperty -InputObject $identitySynchronization -Name 'userSyncInbound') -Name 'isSyncAllowed' } -EvidenceIds @($evidence.Key) -Source @{ collector = 'crossTenantAccess' }) ) } $result.Metrics = @{ defaultPolicyCount = 1 partnerCount = $partnerResponse.Items.Count requestCount = $defaultResponse.Metrics.requestCount + $partnerResponse.Metrics.requestCount retryCount = $defaultResponse.Metrics.retryCount + $partnerResponse.Metrics.retryCount } return $result } function Get-AtlasApplicationManagementPolicy { [CmdletBinding()] param( [Parameter(Mandatory)] [string] $TenantId, [Parameter(Mandatory)] [AllowEmptyCollection()] [AtlasNode[]] $KnownNode ) $result = [AtlasCollectionResult]::new() $defaultEndpoint = '/v1.0/policies/defaultAppManagementPolicy' $policiesEndpoint = '/v1.0/policies/appManagementPolicies' $keyById = @{} $applicationNode = @() foreach ($node in $KnownNode) { $keyById[$node.Id] = $node.Key if ($node.Kind -in @('application', 'servicePrincipal')) { $applicationNode += $node } } $defaultResponse = Invoke-AtlasGraphRequest -Uri $defaultEndpoint $defaultPolicy = @($defaultResponse.Items)[0] if ($null -eq $defaultPolicy) { $result.Status = 'partial' $result.Warnings.Add('The default application management policy returned no data.') return $result } $defaultNode = New-AtlasNode -TenantId $TenantId -Id 'appManagementPolicy:default' -Kind 'applicationManagementPolicy' -DisplayName $( $name = Get-AtlasResponseProperty -InputObject $defaultPolicy -Name 'displayName' if ($name) { $name } else { 'Default application management policy' } ) -Properties @{ description = Get-AtlasResponseProperty -InputObject $defaultPolicy -Name 'description' isEnabled = Get-AtlasResponseProperty -InputObject $defaultPolicy -Name 'isEnabled' applicationRestrictions = Get-AtlasResponseProperty -InputObject $defaultPolicy -Name 'applicationRestrictions' servicePrincipalRestrictions = Get-AtlasResponseProperty -InputObject $defaultPolicy -Name 'servicePrincipalRestrictions' policyType = 'tenantDefault' } -Source @{ provider = 'microsoftGraph' apiVersion = 'v1.0' odataType = '#microsoft.graph.tenantAppManagementPolicy' resourcePath = '/policies/defaultAppManagementPolicy' collector = 'applicationManagementPolicies' } -Tags @('applicationPolicy', 'defaultPolicy') $result.Nodes.Add($defaultNode) $policyResponse = Invoke-AtlasGraphRequest -Uri $policiesEndpoint $customTargetId = @{} foreach ($policy in $policyResponse.Items) { $policyNode = New-AtlasNode -TenantId $TenantId -Id "appManagementPolicy:$($policy.id)" -Kind 'applicationManagementPolicy' -DisplayName $policy.displayName -Properties @{ policyId = $policy.id description = Get-AtlasResponseProperty -InputObject $policy -Name 'description' isEnabled = Get-AtlasResponseProperty -InputObject $policy -Name 'isEnabled' restrictions = Get-AtlasResponseProperty -InputObject $policy -Name 'restrictions' policyType = 'custom' } -Source @{ provider = 'microsoftGraph' apiVersion = 'v1.0' odataType = '#microsoft.graph.appManagementPolicy' resourcePath = "/policies/appManagementPolicies/$($policy.id)" collector = 'applicationManagementPolicies' } -Tags @('applicationPolicy', 'customPolicy') $result.Nodes.Add($policyNode) $appliesToEndpoint = "/v1.0/policies/appManagementPolicies/$($policy.id)/appliesTo?`$select=id,appId,displayName,createdDateTime" try { $appliesToResponse = Invoke-AtlasGraphRequest -Uri $appliesToEndpoint $policyResponse.Metrics.requestCount += $appliesToResponse.Metrics.requestCount $policyResponse.Metrics.retryCount += $appliesToResponse.Metrics.retryCount } catch { $result.Status = 'partial' $result.Warnings.Add("Applications governed by policy '$($policy.displayName)' could not be collected: $(Get-AtlasSafeErrorDetail -ErrorRecord $_)") continue } foreach ($target in $appliesToResponse.Items) { $targetId = Get-AtlasResponseProperty -InputObject $target -Name 'id' if (-not $targetId) { continue } $customTargetId[$targetId] = $true if ($keyById.ContainsKey($targetId)) { $targetKey = $keyById[$targetId] } else { $odataType = Get-AtlasResponseProperty -InputObject $target -Name '@odata.type' $targetKind = if ($odataType -eq '#microsoft.graph.application') { 'application' } else { 'servicePrincipal' } $targetName = Get-AtlasResponseProperty -InputObject $target -Name 'displayName' if (-not $targetName) { $targetName = $targetId } $targetNode = New-AtlasNode -TenantId $TenantId -Id $targetId -Kind $targetKind -DisplayName $targetName -Status 'partial' -Source @{ provider = 'microsoftGraph' apiVersion = 'v1.0' odataType = $odataType resourcePath = "/directoryObjects/$targetId" collector = 'applicationManagementPolicies' } $result.Nodes.Add($targetNode) $targetKey = $targetNode.Key } $evidence = New-AtlasEvidence -TenantId $TenantId -Collector 'applicationManagementPolicies' -Endpoint $appliesToEndpoint -SourceObjectId "$targetId|$($policy.id)" -Fields @{ targetId = $targetId policyId = $policy.id policyType = 'custom' } $result.Evidence.Add($evidence) $result.Edges.Add( (New-AtlasEdge -TenantId $TenantId -From $targetKey -To $policyNode.Key -Relationship 'governedByAppManagementPolicy' -State @{ assignment = 'explicit' policyEnabled = Get-AtlasResponseProperty -InputObject $policy -Name 'isEnabled' } -EvidenceIds @($evidence.Key) -Source @{ collector = 'applicationManagementPolicies' }) ) } } foreach ($node in $applicationNode) { if ($customTargetId.ContainsKey($node.Id)) { continue } $evidence = New-AtlasEvidence -TenantId $TenantId -Collector 'applicationManagementPolicies' -Endpoint $defaultEndpoint -SourceObjectId "$($node.Id)|default" -Fields @{ targetId = $node.Id policyId = 'default' policyType = 'tenantDefault' appliesByDefault = $true } $result.Evidence.Add($evidence) $result.Edges.Add( (New-AtlasEdge -TenantId $TenantId -From $node.Key -To $defaultNode.Key -Relationship 'governedByDefaultAppManagementPolicy' -State @{ assignment = 'default' policyEnabled = Get-AtlasResponseProperty -InputObject $defaultPolicy -Name 'isEnabled' } -EvidenceIds @($evidence.Key) -Source @{ collector = 'applicationManagementPolicies'; inference = 'documentedDefault' }) ) } $result.Metrics = @{ defaultPolicyCount = 1 customPolicyCount = $policyResponse.Items.Count explicitlyGovernedObjectCount = $customTargetId.Count defaultGovernedObjectCount = @($applicationNode | Where-Object { -not $customTargetId.ContainsKey($_.Id) }).Count requestCount = $defaultResponse.Metrics.requestCount + $policyResponse.Metrics.requestCount retryCount = $defaultResponse.Metrics.retryCount + $policyResponse.Metrics.retryCount } return $result } |