Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restrict nested object creation and generation #5519

Merged
merged 2 commits into from
Dec 10, 2024
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 @@ -4,6 +4,10 @@

* IntuneFirewallPolicyWindows10
* Fix export of properties that appear multiple times in subsections.
* M365DSCDRGUtil
* Improve settings catalog handling for nested objects.
* M365DSCResourceGenerator
* Fixes an issue with nested object creation.

# 1.24.1204.1

Expand Down
34 changes: 28 additions & 6 deletions Modules/Microsoft365DSC/Modules/M365DSCDRGUtil.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -831,7 +831,11 @@ function Convert-M365DSCDRGComplexTypeToHashtable

[Parameter()]
[switch]
$SingleLevel
$SingleLevel,

[Parameter()]
[switch]
$ExcludeUnchangedProperties
)

if ($null -eq $ComplexObject)
Expand All @@ -854,6 +858,24 @@ function Convert-M365DSCDRGComplexTypeToHashtable
#However, an array can be preserved on return by prepending it with the array construction operator (,)
return , [hashtable[]]$results
}

if ($SingleLevel)
{
$returnObject = @{}
$keys = $ComplexObject.CimInstanceProperties | Where-Object -FilterScript { $_.Name -ne 'PSComputerName' }
foreach ($key in $keys)
{
if ($ExcludeUnchangedProperties -and -not $key.IsValueModified)
{
continue
}
$propertyName = $key.Name[0].ToString().ToLower() + $key.Name.Substring(1, $key.Name.Length - 1)
$propertyValue = $ComplexObject.$($key.Name)
$returnObject.Add($propertyName, $propertyValue)
}
return [hashtable]$returnObject
}

$hashComplexObject = Get-M365DSCDRGComplexTypeToHashtable -ComplexObject $ComplexObject

if ($null -ne $hashComplexObject)
Expand Down Expand Up @@ -1656,8 +1678,8 @@ function Get-IntuneSettingCatalogPolicySetting
$userSettingTemplates = $SettingTemplates | Where-object -FilterScript {
$_.SettingInstanceTemplate.SettingDefinitionId.StartsWith("user_")
}
$deviceDscParams = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $DSCParams.DeviceSettings -SingleLevel
$userDscParams = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $DSCParams.UserSettings -SingleLevel
$deviceDscParams = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $DSCParams.DeviceSettings -SingleLevel -ExcludeUnchangedProperties
$userDscParams = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $DSCParams.UserSettings -SingleLevel -ExcludeUnchangedProperties
$combinedSettingInstances = @()
$combinedSettingInstances += Get-IntuneSettingCatalogPolicySetting -DSCParams $deviceDscParams -SettingTemplates $deviceSettingTemplates
$combinedSettingInstances += Get-IntuneSettingCatalogPolicySetting -DSCParams $userDscParams -SettingTemplates $userSettingTemplates
Expand Down Expand Up @@ -1692,8 +1714,8 @@ function Get-IntuneSettingCatalogPolicySetting
}
$settingValueName = $settingType.Replace('#microsoft.graph.deviceManagementConfiguration', '').Replace('Instance', 'Value')
$settingValueName = $settingValueName.Substring(0, 1).ToLower() + $settingValueName.Substring(1, $settingValueName.length - 1 )
$settingValueType = $settingInstanceTemplate.AdditionalProperties."$($settingValueName)Template".'@odata.type'
if ($null -ne $settingValueType)
[string]$settingValueType = $settingInstanceTemplate.AdditionalProperties."$($settingValueName)Template".'@odata.type'
if (-not [System.String]::IsNullOrEmpty($settingValueType))
{
$settingValueType = $settingValueType.Replace('ValueTemplate', 'Value')
}
Expand Down Expand Up @@ -1838,7 +1860,7 @@ function Get-IntuneSettingCatalogPolicySettingInstanceValue
$DSCParams = @{
$cimDSCParamsName = if ($instanceCount -eq 1) { $newDSCParams.$cimDSCParamsName[0] } else { $newDSCParams.$cimDSCParamsName }
}
$AllSettingDefinitions = $groupSettingCollectionDefinitionChildren
$AllSettingDefinitions = $groupSettingCollectionDefinitionChildren + $SettingDefinition
}

for ($i = 0; $i -lt $instanceCount; $i++)
Expand Down
112 changes: 74 additions & 38 deletions ResourceGenerator/M365DSCResourceGenerator.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -388,42 +388,7 @@ $($userDefinitionSettings.MOF -join "`r`n")
{
$parameter -match '\$.*$'
$parameterName = $Matches[0].Replace('$', '')
$parameterType = 'IntuneSettingsCatalog' + $parameterName + $(if ($parameterName -in @('DeviceSettings', 'UserSettings')) { "_$ResourceName" })
$cimInstance = $definitionSettings.MOFInstance | Where-Object -FilterScript { $_ -like "*$parameterType`n*" -or $_ -like "*$parameterType`r`n*" }
$rowFilter = '\[.*;'
$cimRows = [regex]::Matches($cimInstance, $rowFilter) | Foreach-Object {
$_.Value
}
$cimPropertyNamequery = '[a-zA-Z0-9_]+[\[\]]*;'
$cimProperties = @()
foreach ($row in $cimRows)
{
$cimProperties += [regex]::Matches($row, $cimPropertyNamequery) | Foreach-Object {
$props = @{
Name = $_.Value.Replace('[', '').Replace(']', '').Replace(';', '')
IsArray = $_.Value.Contains('[]')
IsComplexType = $row.Contains('EmbeddedInstance')
}
if ($props.IsComplexType)
{
Write-Warning -Message "Attention: No automatic complex type conversion is available for the property $($props.Name) in $parameterName. Please implement the conversion manually."
$props.Type = $row.Split(' ')[2].Replace('EmbeddedInstance("', '').Replace('")]', '')
}
$props
}
}
$parameterInformation += @{
Name = $parameterName
IsComplexType = $true
IsMandatory = $false
IsArray = $parameter -match '\[.*\[\]\]'
Type = $parameterType
Properties = $cimProperties
}

Write-Warning -Message "* Do not forget to replace the value `$getValue.$parameterName with `$policySettings.$parameterName in Get-TargetResource, remove it using `$policySettings.Remove('$parameterName')` and update the description in the MOF template. "
Write-Warning -Message "* Make sure to remove the duplicate entry of '$parameterName' in the MOF template."
Write-Warning -Message "* Check all CimInstanceNames in the `$complexTypeMapping in Export-TargetResource because they are not generated correctly."
$parameterInformation += Get-ComplexParameter -Parameter $parameterName -CimInstance $definitionSettings.MOFInstance -ResourceName $ResourceName
}

Write-Warning -Message "* Update all occurences of 'Name' from parameters to 'DisplayName', since security and settings catalog policies use 'Name' internally, but the DSC resource uses 'DisplayName' for clarity."
Expand Down Expand Up @@ -1375,6 +1340,77 @@ class MSFT_DeviceManagementConfigurationPolicyAssignments
}
}

function Get-ComplexParameter {
param (
[Parameter(Mandatory = $true)]
[System.String]
$Parameter,

[Parameter(Mandatory = $true)]
[System.String]
$CimInstance,

[Parameter(Mandatory = $true)]
[System.String]
$ResourceName
)

$parameterType = 'IntuneSettingsCatalog' + $Parameter + $(if ($Parameter -in @('DeviceSettings', 'UserSettings')) { "_$ResourceName" })
$filteredCimInstance = $CimInstance | Where-Object -FilterScript { $_ -like "*$parameterType`n*" -or $_ -like "*$parameterType`r`n*" }
$splittedCimInstance = $filteredCimInstance.Split("`n")
$rowFilter = '\[.*;'
$startRow = for ($i = 0; $i -lt $splittedCimInstance.Count; $i++) {
if ($splittedCimInstance[$i] -like "*$parameterType*")
{
$i
break
}
}
$endRow = for ($i = $startRow; $i -lt $splittedCimInstance.Count; $i++) {
if ($splittedCimInstance[$i] -like "*};*")
{
$i
break
}
}

$cimInstanceOfInterest = $splittedCimInstance[$startRow..$endRow]
$cimRows = [regex]::Matches($cimInstanceOfInterest -join "`n", $rowFilter) | Foreach-Object {
$_.Value
}
$cimPropertyNamequery = '[a-zA-Z0-9_]+[\[\]]*;'
$cimProperties = @()
foreach ($row in $cimRows)
{
$cimProperties += [regex]::Matches($row, $cimPropertyNamequery) | Foreach-Object {
$props = @{
Name = $_.Value.Replace('[', '').Replace(']', '').Replace(';', '')
IsArray = $_.Value.Contains('[]')
IsComplexType = $row.Contains('EmbeddedInstance')
}
if ($props.IsComplexType)
{
Write-Warning -Message "Attention: No automatic complex type conversion is available for the property $($props.Name) in $parameterName. Please implement the conversion manually."
$props.Type = $row.Split(', ')[2].Replace('EmbeddedInstance("', '').Split(' ')[0].Replace('")]', '')
$props.Properties = (Get-ComplexParameter -Parameter $props.Name -CimInstance $CimInstance -ResourceName $ResourceName).Properties
}
$props
}
}
@{
Name = $parameterName
IsComplexType = $true
IsMandatory = $false
IsArray = $parameter -match '\[.*\[\]\]'
Type = $parameterType
Properties = $cimProperties
}

Write-Warning -Message "* Do not forget to replace the value `$getValue.$parameterName with `$policySettings.$parameterName in Get-TargetResource, remove it using `$policySettings.Remove('$parameterName')` and update the description in the MOF template. "
Write-Warning -Message "* Make sure to remove the duplicate entry of '$parameterName' in the MOF template."
Write-Warning -Message "* Check all CimInstanceNames in the `$complexTypeMapping in Export-TargetResource because they are not generated correctly."
}

function Get-MgGraphModuleCmdLetDifference
{
$modules = Get-Module -Name Microsoft.Graph.* -ListAvailable | Sort-Object -Property Name, Version | Out-GridView -PassThru
Expand Down Expand Up @@ -3933,8 +3969,8 @@ function New-SettingsCatalogSettingDefinitionSettingsFromTemplate {
}

$instanceName = "MSFT_MicrosoftGraphIntuneSettingsCatalog"
if (($Level -gt 1 -and $type -like "GroupCollection*" -and $childSettings.Count -gt 1) -or
($Level -eq 1 -and $type -like "GroupCollection*" -and $childSettings.Count -ge 1 -and $childSettings.AdditionalProperties.'@odata.type' -notcontains "#microsoft.graph.deviceManagementConfigurationSettingGroupCollectionDefinition"))
if (($Level -gt 1 -and $type -like "GroupCollection*" -and $childSettings.Count -gt 1) -or
($Level -eq 1 -and $type -eq "GroupCollectionCollection" -and $childSettings.Count -ge 1 -and $childSettings.AdditionalProperties.'@odata.type' -notcontains "#microsoft.graph.deviceManagementConfigurationSettingGroupCollectionDefinition"))
{
$instanceName = $ParentInstanceName + $settingName
}
Expand Down