Modules/M365DSCCompare.psm1
|
<#
.SYNOPSIS This module contains the comparison logic for M365DSC. Delegates to the C# ResourceComparer for all type normalization, primary-key alignment, and drift detection. #> Initialize-M365DSCDllLoader -ErrorAction SilentlyContinue $Script:IsPowerShellCore = $PSVersionTable.PSEdition -eq 'Core' function Compare-M365DSCResourceState { [CmdletBinding()] [OutputType([System.Boolean])] param ( [Parameter(Mandatory = $true)] [System.String] $ResourceName, [Parameter(Mandatory = $true)] [System.Collections.Hashtable] $DesiredValues, [Parameter(Mandatory = $true)] [System.Collections.Hashtable] $CurrentValues, [Parameter()] [System.String[]] $ExcludedProperties, [Parameter()] [System.String[]] $IncludedProperties, [Parameter()] [System.Func[Hashtable, Hashtable, Hashtable, [Object[]], Tuple[Hashtable, Hashtable, Hashtable]]] $PostProcessing, [Parameter()] [System.Object[]] $PostProcessingArgs = @() ) $Global:AllDrifts = @{ DriftInfo = @() CurrentValues = @{} DesiredValues = @{} } $Global:PotentialDrifts = @() # Load the schema once via the C# CacheManager (avoids boxing on every call). $currentPath = $PSScriptRoot if (-not [Microsoft365DSC.Cache.CacheManager]::IsSchemaLoaded) { $schemaPath = Join-Path -Path $currentPath -ChildPath '..\SchemaDefinition.json' $schemaContent = [System.IO.File]::ReadAllText($schemaPath) | ConvertFrom-Json [Microsoft365DSC.Cache.CacheManager]::LoadSchema($schemaContent) } # Apply custom post-processing callback if specified. # PostProcessing is a PowerShell Func delegate, so it must be called here (before entering C#). $ValuesToCheck = $DesiredValues.Clone() if ($null -ne $PostProcessing) { Write-Verbose -Message "Applying custom post-processing to CurrentValues and ValuesToCheck for resource $ResourceName" try { $result = $PostProcessing.Invoke($DesiredValues, $CurrentValues, $ValuesToCheck, $PostProcessingArgs) if ($null -ne $result -and $result.Item1 -is [Hashtable] -and $result.Item2 -is [Hashtable] -and $result.Item3 -is [Hashtable]) { $DesiredValues = $result.Item1 $CurrentValues = $result.Item2 $ValuesToCheck = $result.Item3 } else { Write-Warning -Message "PostProcessing function did not return a valid tuple for resource $ResourceName. Using original values." } } catch { Write-Warning -Message "Error occurred during post-processing for resource $ResourceName`: $_" } } Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $DesiredValues)" # Delegate the entire comparison to C#. # ResourceComparer handles: schema lookup, key/credential exclusion, Ensure handling, # CimInstance/PSObject normalization (via ObjectNormalizer), primary-key alignment, # complex object comparison, and simple property comparison. $compareResult = [Microsoft365DSC.Compare.ResourceComparer]::Compare( $DesiredValues, $CurrentValues, $ValuesToCheck, [Microsoft365DSC.Cache.CacheManager]::Schema, $ResourceName, $ExcludedProperties, $IncludedProperties ) # Populate the global drift state from the C# result for downstream consumers # (event logging, telemetry, drift reporting). $testTargetResource = $compareResult.TestResult foreach ($drift in $compareResult.DriftInfo) { $Global:AllDrifts.DriftInfo += @{ PropertyName = $drift['PropertyName'] CurrentValue = $drift['CurrentValue'] DesiredValue = $drift['DesiredValue'] } } return $testTargetResource } Export-ModuleMember -Function Compare-M365DSCResourceState |