internal/functions/Merge-PolicyAssignmentCsvParameterRow.ps1
|
function Merge-PolicyAssignmentCsvParameterRow { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [object[]] $GeneratedRows, [Parameter(Mandatory = $true)] [object[]] $ExistingRows ) if ($GeneratedRows.Count -eq 0) { throw "The generated CSV must contain at least one data row." } if ($ExistingRows.Count -eq 0) { throw "The existing parameter CSV must contain at least one data row." } $generatedHeaders = @($GeneratedRows[0].PSObject.Properties.Name) $existingHeaders = @($ExistingRows[0].PSObject.Properties.Name) $requiredHeaders = @("name", "referencePath") $generatedHeaderLookup = @{} foreach ($header in $generatedHeaders) { if ($generatedHeaderLookup.ContainsKey($header)) { throw "The generated CSV contains duplicate column '$header'." } $generatedHeaderLookup[$header] = $header } $existingHeaderLookup = @{} foreach ($header in $existingHeaders) { if ($existingHeaderLookup.ContainsKey($header)) { throw "The existing parameter CSV contains duplicate column '$header'." } $existingHeaderLookup[$header] = $header } foreach ($requiredHeader in $requiredHeaders) { if (-not $generatedHeaderLookup.ContainsKey($requiredHeader)) { throw "The generated CSV must contain the '$requiredHeader' column." } if (-not $existingHeaderLookup.ContainsKey($requiredHeader)) { throw "The existing parameter CSV must contain the '$requiredHeader' column." } } $separator = [char]31 $getIdentity = { param ( [object] $Row, [hashtable] $HeaderLookup, [string] $SourceName ) $name = [string]$Row.($HeaderLookup["name"]) $referencePath = [string]$Row.($HeaderLookup["referencePath"]) if ([string]::IsNullOrWhiteSpace($name)) { throw "The $SourceName CSV contains a row with an empty 'name' value." } return "$($name.ToLowerInvariant())$separator$($referencePath.ToLowerInvariant())" } $existingRowsByIdentity = @{} foreach ($row in $ExistingRows) { $identity = & $getIdentity $row $existingHeaderLookup "existing parameter" if ($existingRowsByIdentity.ContainsKey($identity)) { throw "The existing parameter CSV contains duplicate rows for name '$($row.($existingHeaderLookup["name"]))' and referencePath '$($row.($existingHeaderLookup["referencePath"]))'." } $existingRowsByIdentity[$identity] = $row } $generatedIdentities = @{} foreach ($row in $GeneratedRows) { $identity = & $getIdentity $row $generatedHeaderLookup "generated" if ($generatedIdentities.ContainsKey($identity)) { throw "The generated CSV contains duplicate rows for name '$($row.($generatedHeaderLookup["name"]))' and referencePath '$($row.($generatedHeaderLookup["referencePath"]))'." } $generatedIdentities[$identity] = $true } [System.Collections.Generic.List[string]] $outputHeaders = [System.Collections.Generic.List[string]]::new() $outputHeaders.AddRange([string[]]$generatedHeaders) foreach ($header in $existingHeaders) { if (-not $generatedHeaderLookup.ContainsKey($header)) { $outputHeaders.Add($header) } } [System.Collections.Generic.List[object]] $mergedRows = [System.Collections.Generic.List[object]]::new() $addedCount = 0 $updatedCount = 0 foreach ($generatedRow in $GeneratedRows) { $identity = & $getIdentity $generatedRow $generatedHeaderLookup "generated" $existingRow = $existingRowsByIdentity[$identity] $isExistingRow = $null -ne $existingRow if ($isExistingRow) { $updatedCount++ } else { $addedCount++ } $mergedRow = [ordered]@{} foreach ($header in $outputHeaders) { $generatedHeader = $generatedHeaderLookup[$header] $existingHeader = $existingHeaderLookup[$header] $preserveExistingValue = $isExistingRow -and $null -ne $existingHeader -and ($header -match "(?i)(Effect|Parameters)$" -or $null -eq $generatedHeader) if ($preserveExistingValue) { $mergedRow[$header] = $existingRow.$existingHeader } elseif ($null -ne $generatedHeader) { $mergedRow[$header] = $generatedRow.$generatedHeader } else { $mergedRow[$header] = "" } } $mergedRows.Add([pscustomobject]$mergedRow) } return [pscustomobject]@{ Headers = [string[]]$outputHeaders Rows = [object[]]$mergedRows AddedCount = $addedCount UpdatedCount = $updatedCount RemovedCount = $ExistingRows.Count - $updatedCount } } |