CloudConfigurationManager.psm1
function Get-CCMPropertiesToSend { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param( [Parameter(Mandatory = $true)] [System.Collections.Hashtable] $Instance, [Parameter()] [System.Collections.Hashtable] $Parameters ) $currentInstance = ([System.Collections.Hashtable]$instance).Clone() $ResourceName = $currentInstance.ResourceName $currentInstance.Remove('ResourceName') | Out-Null $ResourceInstanceName = $currentInstance.ResourceInstanceName $currentInstance.Remove('ResourceInstanceName') | Out-Null # Retrieve information about the DSC resource $dscResourceInfo = Get-DSCResource -Name $ResourceName $propertiesToSend = @{} foreach ($propertyName in $currentInstance.Keys) { # Retrieve the CIM Instance Property. $CimProperty = $dscResourceInfo.Properties | Where-Object -FilterScript {$_.Name -eq $propertyName} # If the current propertry is a CIMInstance if ($CimProperty.PropertyType.StartsWith('[MSFT_')) { $cimResult = @() # Loop through all CIMInstances in the property foreach ($cimEntry in $currentInstance.$propertyName) { $cimInstanceProperties = @{} # Loop through all properties of the CIMInstance foreach ($cimSubPropertyName in $cimEntry.Keys) { if ($cimSubPropertyName -ne 'CIMInstance') { $cimInstanceProperties.Add($cimSubPropertyName, $cimEntry.$cimSubPropertyName) } } $CimInstanceName = ([Array]$currentInstance.$propertyName.CIMInstance)[0] $propertyCIMInstanceValue = New-CimInstance -ClassName $CimInstanceName ` -Property $cimInstanceProperties ` -ClientOnly $cimResult += $propertyCIMInstanceValue } $propertiesToSend.Add($propertyName, [Microsoft.Management.Infrastructure.CimInstance[]]$cimResult) } else { # Property is not a CIMInstance, therefore add it to the list. $propertyValue = $currentInstance.$propertyName # If the property's value is a variable, try to retrieve its value from the list of # parameters provided by the user. if ($propertyValue.StartsWith('$')) { $propertyVariableName = $propertyValue.Substring(1) $propertyValue = $Parameters.$propertyVariableName } # If the property is an empty array, explicitely define it as empty instead of null. if ([System.String]::IsNullOrEmpty($propertyValue) -and $CimProperty.PropertyType.EndsWith('[]]')) { $propertyValue = @('') } $propertiesToSend.Add($propertyName, $propertyValue) } } return $propertiesToSend } function Get-CCMParsedResources { [CmdletBinding()] [OutputType([Array])] param( [Parameter()] [System.String] $Path, [Parameter()] [System.String] $Content ) # Convert the DSC Resources into PowerShell Objects $resourceInstances = $null if (-not [System.String]::IsNullOrEmpty($Path)) { $resourceInstances = ConvertTo-DSCObject -Path $path } elseif (-not [System.String]::IsNullOrEmpty($Content)) { $resourceInstances = ConvertTo-DSCObject -Content $Content } return $resourceInstances } function Test-CCMConfiguration { [CmdletBinding()] [OutputType([System.Boolean])] param( [Parameter(Mandatory = $true)] [System.String] $ModuleName, [Parameter(ParameterSetName = 'Path')] [System.String] $Path, [Parameter(ParameterSetName = 'Content')] [System.String] $Content, [Parameter()] [System.Collections.Hashtable] $Parameters ) $TestResult = $true $Global:CCMAllDrifts = @() $currentLoadedModule = '' $currentInstance = $null $resourceInstances = Get-CCMParsedResources -Path $Path ` -Content $Content foreach ($instance in $resourceInstances) { $ResourceName = $instance.ResourceName $ResourceInstanceName = $instance.ResourceInstanceName $propertiesToSend = Get-CCMPropertiesToSend -Instance $instance ` -Parameters $Parameters # Load the resource's module. if ($resourceName -ne $currentLoadedModule) { $ResourceInfo = Get-DSCResource -Name $ResourceName Import-Module $ResourceInfo.Path -Force $currentLoadedModule = $resourceName } # Evaluate the properties of the current resource. $currentResult = Test-TargetResource @propertiesToSend # If a drift was detected, augment its related info with the name of the # current instance and collect it in the CCMAllDrifts Global Variable. if (-not $currentResult) { $TestResult = $false $currentDrift = $Global:M365DSCCurrentDriftInfo $currentDrift.Add('InstanceName', $ResourceInstanceName) $Global:CCMAllDrifts += $currentDrift } } return $TestResult } |