Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ The format follows [Conventional Commits](https://www.conventionalcommits.org/)

## Unreleased

### Fixes

- **Deprecated settings carry the configured value by its Intune name** (`False` instead of `com.apple.applicationaccess_allowgenmoji_false`). The Maester pack shows it; the HTML report does not show this column.

## [1.3.0] - 2026-10-26

Release for the Intune Anomalies report.
Expand Down
21 changes: 21 additions & 0 deletions Tests/IntuneAnomalyCore.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,27 @@ Describe 'Resolvers' {
@($r.Rows).SettingDisplayName | Should -Be @('Old thing (Deprecated)')
@($r.Rows)[0].DetectionSource | Should -Be 'CatalogDisplayName'
}
It 'Deprecated: shows the option label as the configured value, else the part after the definition id, and keeps simple values' {
$r = InModuleScope RKSolutions {
$choice = '#microsoft.graph.deviceManagementConfigurationChoiceSettingInstance'
$policy = [pscustomobject]@{ id = 'p1'; name = 'Pol'; platforms = 'macOS'; settings = @(
[pscustomobject]@{
settingInstance = [pscustomobject]@{ '@odata.type' = $choice; settingDefinitionId = 'def_a'; choiceSettingValue = [pscustomobject]@{ value = 'def_a_false' } }
settingDefinitions = @([pscustomobject]@{ id = 'def_a'; displayName = 'A (Deprecated)'; options = @([pscustomobject]@{ itemId = 'def_a_false'; displayName = 'False' }) })
}
[pscustomobject]@{
settingInstance = [pscustomobject]@{ '@odata.type' = $choice; settingDefinitionId = 'def_b'; choiceSettingValue = [pscustomobject]@{ value = 'def_b_1' } }
settingDefinitions = @([pscustomobject]@{ id = 'def_b'; displayName = 'B (Deprecated)' })
}
[pscustomobject]@{
settingInstance = [pscustomobject]@{ '@odata.type' = '#microsoft.graph.deviceManagementConfigurationSimpleSettingInstance'; settingDefinitionId = 'def_c'; simpleSettingValue = [pscustomobject]@{ value = 'def_c_custom' } }
settingDefinitions = @([pscustomobject]@{ id = 'def_c'; displayName = 'C (Deprecated)' })
}) }
$d = [pscustomobject]@{ TenantName = 'T'; SecurityKeyContext = [pscustomobject]@{ ConfigurationPolicies = @($policy) }; Warnings = @() }
Resolve-IntuneDeprecatedAnomalies -Data $d
}
@($r.Rows).ConfiguredValue | Should -Be @('False', '1', 'def_c_custom')
}
}

Describe 'Unreadable keys, settings fallback and null children' {
Expand Down
30 changes: 28 additions & 2 deletions module/Core/IntuneAnomalyResolvers.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,25 @@ function Get-IntuneSettingValueString {
}
}

function Get-IntuneSettingValueLabel {
<#
Turns a choice value such as com.apple.applicationaccess_allowgenmoji_false into its label from the
expanded setting definition ("False"), or into the part after the definition id ("false") when the
definition has no label for it. Other values come back as they are. Collection values are mapped one by one.
#>
[CmdletBinding()]
[OutputType([string])]
param([string] $DefinitionId, [string] $Value, [hashtable] $Catalog)

$options = if ($Catalog -and $DefinitionId -and $Catalog.ContainsKey($DefinitionId)) { $Catalog[$DefinitionId].Options }
$labels = foreach ($v in ($Value -split '; ')) {
if ($options -and $options[$v]) { $options[$v] }
elseif ($DefinitionId -and $v.StartsWith("${DefinitionId}_")) { $v.Substring($DefinitionId.Length + 1) }
else { $v }
}
return (@($labels) -join '; ')
}

function Get-IntuneSettingDeprecations {
<#
Recursively walk a settingInstance (and any nested group children) and
Expand All @@ -476,7 +495,8 @@ function Get-IntuneSettingDeprecations {
$hits.Add([PSCustomObject]@{
DefinitionId = $defId
DisplayName = if ([string]::IsNullOrWhiteSpace($check.DisplayName)) { $defId } else { $check.DisplayName }
Value = $value
# Only choice values are option ids; a simple value is what the admin typed and stays as it is.
Value = if ([string]$SettingInstance.'@odata.type' -like '*choiceSetting*') { Get-IntuneSettingValueLabel -DefinitionId $defId -Value $value -Catalog $Catalog } else { $value }
Source = $check.Source
})
}
Expand Down Expand Up @@ -513,7 +533,13 @@ function Resolve-IntuneDeprecatedAnomalies {
$catalog = @{}
foreach ($policy in $Context.ConfigurationPolicies) {
foreach ($s in @($policy.settings)) {
foreach ($def in @($s.settingDefinitions)) { if ($def.id -and -not $catalog.ContainsKey([string]$def.id)) { $catalog[[string]$def.id] = [pscustomobject]@{ DisplayName = [string]$def.displayName } } }
foreach ($def in @($s.settingDefinitions)) {
if (-not $def.id -or $catalog.ContainsKey([string]$def.id)) { continue }
# Choice definitions carry their options: itemId (the configured value) -> displayName (its label).
$options = @{}
foreach ($o in @($def.options)) { if ($o.itemId) { $options[[string]$o.itemId] = [string]$o.displayName } }
$catalog[[string]$def.id] = [pscustomobject]@{ DisplayName = [string]$def.displayName; Options = $options }
}
}
}
$out = [System.Collections.Generic.List[PSObject]]::new()
Expand Down
7 changes: 3 additions & 4 deletions module/Private/IntuneAnomalies.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -188,10 +188,9 @@ function New-IntuneAnomaliesHTMLReport {
}

# Generate table rows for deprecated Settings Catalog settings.
# Customer / ConfiguredValue / DetectionSource intentionally omitted - they're
# either constant (Customer) or redundant with the Setting Definition ID for
# the common choice-setting case where Value == DefId + "_<n>". The full
# record still carries those fields for downstream consumers.
# Customer / ConfiguredValue / DetectionSource intentionally omitted - Customer
# is constant here. The full record still carries those fields for downstream
# consumers such as the Maester pack, which shows ConfiguredValue.
$deprecatedSettingsRows = ""
foreach ($item in $Report_DeprecatedSettings) {
$deprecatedSettingsRows += @"
Expand Down
Loading