Private/Get-IntuneAccessActionCentre.ps1
|
function Get-IntuneAccessActionCentre { [CmdletBinding()] param( [Parameter(Mandatory)] [object] $Collection, [AllowEmptyCollection()] [object[]] $PreviousOutcome = @(), [DateTimeOffset] $AsOf = [DateTimeOffset]::UtcNow ) $findings = [Collections.Generic.List[object]]::new() foreach ($existing in @(Get-IntuneAccessProperty $Collection 'EstateFindings' @())) { $findings.Add($existing.PSObject.Copy()) } foreach ($conflict in @(Get-IntuneAccessProperty $Collection 'PolicyConflictFindings' @() | Where-Object FindingState -EQ 'PotentialConflict')) { $findings.Add([pscustomobject] @{ FindingId = "POLICY/$($conflict.Id)"; Title = "Potential setting conflict: $($conflict.SettingDefinitionId)"; PriorityScore = 60; Severity = 'Medium' Category = 'Configuration'; DeviceId = ''; DeviceName = ''; SourceType = 'PolicyConflict'; SourceId = [string] $conflict.Id EvidenceTimestamp = Get-IntuneAccessProperty $Collection 'GeneratedAt'; Explanation = [string] $conflict.Reason ReviewRecommendation = 'Review both configured values and target overlap before proposing consolidation.'; CauseState = 'NotAsserted'; Evidence = $conflict }) } foreach ($assignment in @(Get-IntuneAccessProperty $Collection 'DeviceAssignmentExplanations' @())) { $required = @((Get-IntuneAccessProperty $assignment 'AssignmentPaths' @()) | Where-Object { (Get-IntuneAccessProperty $_ 'Intent' '') -eq 'required' -and (Get-IntuneAccessProperty $_ 'PathState' '') -eq 'Included' }) if ($assignment.WorkloadType -eq 'Applications' -and $assignment.AssignmentState -eq 'Included' -and $assignment.ReportedOutcomeState -eq 'NoReportedEvidence' -and $required.Count -gt 0) { $findings.Add([pscustomobject] @{ FindingId = "MISSING-RESULT/$($assignment.WorkloadId)/$($assignment.DeviceId)"; Title = "Required application has no reported result: $($assignment.WorkloadName)"; PriorityScore = 45; Severity = 'Information' Category = 'Application'; DeviceId = [string] $assignment.DeviceId; DeviceName = [string] $assignment.DeviceName; SourceType = 'ApplicationEvidence'; SourceId = [string] $assignment.WorkloadId EvidenceTimestamp = Get-IntuneAccessProperty $assignment 'GeneratedAt'; Explanation = 'An included required path was calculated, but no device outcome was returned. This is an evidence gap, not a proven installation failure.' ReviewRecommendation = 'Review reporting coverage and client detection evidence.'; CauseState = 'NotAsserted'; Evidence = $assignment }) } } $effectiveness = @(Get-IntuneAccessRemediationEffectiveness -Outcome @(Get-IntuneAccessProperty $Collection 'DeploymentOutcomes' @()) -PreviousOutcome $PreviousOutcome -Workload @(Get-IntuneAccessProperty $Collection 'WorkloadObjects' @()) -CollectionStatus @(Get-IntuneAccessProperty $Collection 'OutcomeCollectionStatus' @()) -AsOf $AsOf) foreach ($item in $effectiveness) { if ($item.FindingState -in @('ScriptError', 'RemediationFailed', 'DetectedWithoutSuccessfulRemediation', 'StaleReporting', 'NoReportedResults', 'MissingReportedResult', 'NotEvaluated') -or $item.HistoryState -in @('RepeatedDetection', 'IssueReturnedAfterClearDetection', 'PersistentScriptError')) { $findings.Add([pscustomobject] @{ FindingId = [string] $item.Id; Title = "$($item.WorkloadName): $($item.FindingState)"; PriorityScore = 55; Severity = 'Medium' Category = 'Remediation'; DeviceId = [string] $item.DeviceId; DeviceName = [string] $item.DeviceName; SourceType = 'RemediationEffectiveness'; SourceId = [string] $item.WorkloadId EvidenceTimestamp = $item.EvidenceTimestamp; Explanation = [string] $item.Explanation ReviewRecommendation = 'Review separate script states and distinct execution observations.'; CauseState = 'NotAsserted'; Evidence = $item }) } } foreach ($finding in $findings) { foreach ($name in @('DeviceId', 'DeviceName', 'SourceId', 'SourceType', 'EvidenceTimestamp', 'Evidence')) { if ($null -eq $finding.PSObject.Properties[$name]) { $finding | Add-Member -NotePropertyName $name -NotePropertyValue $null } } $finding | Add-Member -NotePropertyName ResolutionGuide -NotePropertyValue (Get-IntuneAccessResolutionGuide -Finding $finding) -Force $finding | Add-Member -NotePropertyName CollectedAt -NotePropertyValue $AsOf -Force $finding | Add-Member -NotePropertyName AffectedObjects -NotePropertyValue @( if ($finding.DeviceId) { [pscustomobject] @{ Type = 'Device'; Id = $finding.DeviceId; Name = $finding.DeviceName } } if ($finding.SourceType -eq 'PolicyConflict') { [pscustomobject] @{ Type = 'Policy'; Id = $finding.Evidence.FirstPolicyId; Name = $finding.Evidence.FirstPolicyName } [pscustomobject] @{ Type = 'Policy'; Id = $finding.Evidence.SecondPolicyId; Name = $finding.Evidence.SecondPolicyName } } elseif ($finding.SourceType -ne 'DeviceHygiene') { [pscustomobject] @{ Type = $finding.SourceType; Id = $finding.SourceId; Name = $finding.Title } } ) -Force } [pscustomobject] @{ Findings = @($findings | Sort-Object PriorityScore -Descending) RemediationEffectiveness = $effectiveness ReadOnly = $true; GeneratedAt = $AsOf } } |