Private/Logic/ConvertTo-IntuneSettingInstance.ps1
|
# Copyright (c) 2026 Sandy Zeng. All rights reserved. # Source-available. All rights reserved. See LICENSE file. <# ConvertTo-IntuneSettingInstance.ps1 — Cleans a raw Graph setting instance into the shape Intune's import accepts. Author: Sandy Zeng Project: IntuneDiff Version History: 1.0.0 Initial release. #> function ConvertTo-IntuneSettingInstance { <# .SYNOPSIS Cleans a raw Graph settingInstance (or settingInstanceTemplate) into the Settings-Catalog instance shape that Intune's import accepts. .DESCRIPTION PowerShell port of intuneExportUtils.cleanSettingInstance from IntuneDiff-v2. Handles choice/simple/group/collection settings and converts Security Baseline templates into instances. Recurses into children. #> [CmdletBinding()] param( [Parameter(Mandatory)] $SettingInstance ) if (-not $SettingInstance) { return $null } $odata = [string]$SettingInstance.'@odata.type' if ($odata -like '*Template*') { $odata = $odata -replace 'Template', '' } $cleaned = [ordered]@{ '@odata.type' = $odata 'settingDefinitionId' = $SettingInstance.settingDefinitionId 'settingInstanceTemplateReference' = $null } # Choice if ($SettingInstance.choiceSettingValueTemplate) { $dv = $SettingInstance.choiceSettingValueTemplate.defaultValue $cleaned['choiceSettingValue'] = [ordered]@{ 'settingValueTemplateReference' = $null 'value' = if ($dv -and $dv.settingDefinitionOptionId) { [string]$dv.settingDefinitionOptionId } else { '' } 'children' = @(if ($dv -and $dv.children) { foreach ($c in $dv.children) { ConvertTo-IntuneSettingInstance -SettingInstance $c } } else { @() }) } } elseif ($SettingInstance.choiceSettingValue) { $csv = $SettingInstance.choiceSettingValue $cleaned['choiceSettingValue'] = [ordered]@{ 'settingValueTemplateReference' = $null 'value' = $csv.value 'children' = @(if ($csv.children) { foreach ($c in $csv.children) { ConvertTo-IntuneSettingInstance -SettingInstance $c } } else { @() }) } } # Simple if ($SettingInstance.simpleSettingValueTemplate) { $dv = $SettingInstance.simpleSettingValueTemplate.defaultValue $val = if ($null -ne $dv.constantValue) { $dv.constantValue } else { $dv.value } $cleaned['simpleSettingValue'] = [ordered]@{ '@odata.type' = Get-SimpleSettingValueType -Value $val 'settingValueTemplateReference' = $null 'value' = $val } } elseif ($SettingInstance.simpleSettingValue) { $ssv = $SettingInstance.simpleSettingValue $cleaned['simpleSettingValue'] = [ordered]@{ '@odata.type' = $ssv.'@odata.type' 'settingValueTemplateReference' = $null 'value' = $ssv.value } } # Simple collection if ($SettingInstance.simpleSettingCollectionValueTemplate) { $cleaned['simpleSettingCollectionValue'] = @( foreach ($item in @($SettingInstance.simpleSettingCollectionValueTemplate)) { $dv = $item.defaultValue $val = if ($null -ne $dv.constantValue) { $dv.constantValue } else { $dv.value } [ordered]@{ '@odata.type' = Get-SimpleSettingValueType -Value $val 'settingValueTemplateReference' = $null 'value' = $val } } ) } elseif ($SettingInstance.simpleSettingCollectionValue) { $cleaned['simpleSettingCollectionValue'] = @( foreach ($item in @($SettingInstance.simpleSettingCollectionValue)) { [ordered]@{ '@odata.type' = $item.'@odata.type' 'settingValueTemplateReference' = $null 'value' = $item.value } } ) } # Group collection if ($SettingInstance.groupSettingCollectionValueTemplate) { $cleaned['groupSettingCollectionValue'] = @( foreach ($item in @($SettingInstance.groupSettingCollectionValueTemplate)) { [ordered]@{ 'settingValueTemplateReference' = $null 'children' = @(if ($item.children) { foreach ($c in $item.children) { ConvertTo-IntuneSettingInstance -SettingInstance $c } } else { @() }) } } ) } elseif ($SettingInstance.groupSettingCollectionValue) { $cleaned['groupSettingCollectionValue'] = @( foreach ($item in @($SettingInstance.groupSettingCollectionValue)) { [ordered]@{ 'settingValueTemplateReference' = $null 'children' = @(if ($item.children) { foreach ($c in $item.children) { ConvertTo-IntuneSettingInstance -SettingInstance $c } } else { @() }) } } ) } # Choice collection if ($SettingInstance.choiceSettingCollectionValueTemplate) { $cleaned['choiceSettingCollectionValue'] = @( foreach ($item in @($SettingInstance.choiceSettingCollectionValueTemplate)) { $dv = $item.defaultValue [ordered]@{ 'settingValueTemplateReference' = $null 'value' = if ($dv -and $dv.settingDefinitionOptionId) { [string]$dv.settingDefinitionOptionId } else { '' } 'children' = @(if ($dv -and $dv.children) { foreach ($c in $dv.children) { ConvertTo-IntuneSettingInstance -SettingInstance $c } } else { @() }) } } ) } elseif ($SettingInstance.choiceSettingCollectionValue) { $cleaned['choiceSettingCollectionValue'] = @( foreach ($item in @($SettingInstance.choiceSettingCollectionValue)) { [ordered]@{ 'settingValueTemplateReference' = $null 'value' = $item.value 'children' = @(if ($item.children) { foreach ($c in $item.children) { ConvertTo-IntuneSettingInstance -SettingInstance $c } } else { @() }) } } ) } return [pscustomobject]$cleaned } function Get-SimpleSettingValueType { <# .SYNOPSIS Returns the Graph @odata.type string for a simple setting value based on its .NET type. #> param($Value) if ($Value -is [int] -or $Value -is [long] -or $Value -is [double]) { return '#microsoft.graph.deviceManagementConfigurationIntegerSettingValue' } if ($Value -is [bool]) { return '#microsoft.graph.deviceManagementConfigurationBooleanSettingValue' } return '#microsoft.graph.deviceManagementConfigurationStringSettingValue' } function ConvertTo-IntunePolicyExport { <# .SYNOPSIS Wraps a list of raw Graph settings into a Settings Catalog policy JSON document that can be re-imported into Intune. .PARAMETER RawSettings Array of raw setting objects from Graph (each containing settingInstance or settingInstanceTemplate). Duplicates (by reference) are removed. .PARAMETER PolicyName Name for the exported policy. .PARAMETER Description Optional description string. #> [CmdletBinding()] param( [Parameter(Mandatory)] [object[]]$RawSettings, [Parameter(Mandatory)] [string]$PolicyName, [string]$Description = '' ) $seen = New-Object System.Collections.Generic.HashSet[object] $settings = New-Object System.Collections.Generic.List[object] $idx = 0 foreach ($raw in $RawSettings) { if (-not $raw) { continue } if (-not $seen.Add($raw)) { continue } $instance = $null if ($raw.settingInstance) { $instance = ConvertTo-IntuneSettingInstance -SettingInstance $raw.settingInstance } elseif ($raw.settingInstanceTemplate) { $instance = ConvertTo-IntuneSettingInstance -SettingInstance $raw.settingInstanceTemplate } if (-not $instance) { continue } $settings.Add([pscustomobject][ordered]@{ id = "$idx" settingInstance = $instance }) $idx++ } $now = (Get-Date).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ss.fffZ', [System.Globalization.CultureInfo]::InvariantCulture) $template = [ordered]@{ 'templateId' = '' 'templateFamily' = 'none' 'templateDisplayName' = $null 'templateDisplayVersion' = $null } $envelope = [ordered]@{ '@odata.context' = 'https://graph.microsoft.com/beta/$metadata#deviceManagement/configurationPolicies/$entity' 'createdDateTime' = $now 'creationSource' = $null 'description' = $Description 'lastModifiedDateTime' = $now 'name' = $PolicyName 'platforms' = 'windows10' 'priorityMetaData' = $null 'roleScopeTagIds' = @('0') 'settingCount' = $settings.Count 'technologies' = 'mdm' 'id' = [Guid]::NewGuid().ToString() 'templateReference' = [pscustomobject]$template 'settings' = @($settings.ToArray()) } return [pscustomobject]$envelope } |