functions/ConvertTo-G2DValidation.ps1
<# .SYNOPSIS Generate DSC configuration from PolicyRules XML .DESCRIPTION Convert all PolicyRules files in folder or merge them. To merge PolicyRules files, bring them in a naming pattern that can be treated with the split operator, e.g. <Department> - <OS> - <Version> - <Layer> - <Policyname> For example: SecOps - Windows - v3.1 - Baseline - Audit.PolicyRules The layer index after the split would be 3, so the cmdlet could be called thusly: ConvertTo-G2DValidations -Path . -Pattern ' - ' -LayerIndex 3 -Precendence @(@('Baseline'), @('Baseline', 'DC')) The layers called Baseline and the merger of DC onto Baseline will be converted to DSC configurations .PARAMETER Path Path to PolicyRules files .PARAMETER Precedence The precedence of layers e.g. @('Baseline'), @('Baseline', 'DC') .PARAMETER Pattern The pattern to split the basename of each policy export with .PARAMETER LayerIndex At which index of the split basename is the name of the layer? .PARAMETER SkipMerge Indicates that the precedence and layers should not be used. Instead, each individual file will be converted to a DSC configuration .PARAMETER Pester Export Pester config .EXAMPLE .\ConvertTo-G2DValidation.ps1 -Path D:\pol Without further parameter uses the split regex ' - ', the layer index 4 and the following precedence rules: @('Baseline'), @('Baseline', 'DC'), @('Baseline', 'Server'), @('Baseline', 'Client') .EXAMPLE .\ConvertTo-G2DValidation.ps1 -Path D:\pol -SkipMerge Converts each item to a DSC configuration. #> function ConvertTo-G2DValidation { [CmdletBinding()] [OutputType([ValidationItem])] param ( [Parameter(Mandatory)] [string] $Path, [switch] $SkipMerge, [object[]] $Precedence = @( @('Baseline'), @('Baseline', 'DC'), @('Baseline', 'Server'), @('Baseline', 'Client') ), [string] $Pattern = ' - ', [uint16] $LayerIndex = 4, [switch] $Pester ) if ($SkipMerge) { $policyItems = Get-ChildItem -Path $Path -File -Filter *.PolicyRules | Get-G2DObjectFromPolicyRulesFile if ($Pester.IsPresent) { $policyItems | Group-Object -Property PolicyName | ForEach-Object { $cName = $_.Name [ValidationItem]::new( ($_.Group | Get-G2DPesterString -ConfigurationName $cName), $cName, 'Pester' ) } } $policyItems | Group-Object -Property PolicyName | ForEach-Object { $cName = $_.Name -replace '\s' [ValidationItem]::new( ($_.Group | Get-G2DDscConfigurationString -ConfigurationName $cName), $cName, 'Dsc' ) } return } # Group by layer $gpoFiles = Get-ChildItem -File -Path $Path | Group-Object { ($_.BaseName -split $Pattern)[$LayerIndex] } -AsHashTable -AsString foreach ($layer in $Precedence) { [string[]]$layer = $layer $exportName = $layer -join '-' foreach ($innerLayer in @($layer)) { if (Get-Variable -Name "$($innerLayer)items" -ErrorAction SilentlyContinue) { continue } $policyItems = $gpoFiles.$innerLayer | Get-G2DObjectFromPolicyRulesFile $null = New-Variable -Name "$($innerLayer)items" -Value @{ RegistryItems = $policyItems | Where-Object -FilterScript { $_.ObjectType -eq 'RegistryItem' } | Sort-Object -Unique -Property Key, ValueName UserRightsAssignment = $policyItems | Where-Object -FilterScript { $_.ObjectType -eq 'UserRightsAssignment' } | Sort-Object -Unique -Property Policy SecurityOptions = $policyItems | Where-Object -FilterScript { $_.ObjectType -eq 'SecurityOptions' } | Sort-Object -Unique -Property SettingName AuditPol = $policyItems | Where-Object -FilterScript { $_.ObjectType -eq 'AuditPol' } | Sort-Object -Unique -Property AuditFlag } if ($layer[0] -ne $innerLayer) { $layer0Clone = Get-Variable -Name "$($layer[0])items" $var = Get-Variable -Name "$($innerLayer)items" -ValueOnly foreach ($item in $var.RegistryItems) { $existingObject = $layer0Clone.Value.RegistryItems | Where-Object { $_.ValueName -eq $item.ValueName -and $_.Key -eq $item.Key } if ($existingObject) { $existingObject.ValueData = $item.ValueData } else { $layer0Clone.Value.RegistryItems += $item } } foreach ($uar in $var.UserRightsAssignment) { $layer0Clone.Value.UserRightsAssignment = $layer0Clone.Value.UserRightsAssignment | Where-Object { $_.Policy -ne $uar.Policy } $layer0Clone.Value.UserRightsAssignment += $uar } foreach ($aup in $var.AuditPol) { $layer0Clone.Value.AuditPol = $layer0Clone.Value.AuditPol | Where-Object { $_.Name -ne $aup.Name -and $_.AuditFlag -ne $aup.AuditFlag } $layer0Clone.Value.AuditPol += $aup } foreach ($secp in $var.SecurityOptions) { $layer0Clone.Value.SecurityOptions = $layer0Clone.Value.SecurityOptions | Where-Object { $_.Name -ne $secp.SettingName } $layer0Clone.Value.SecurityOptions += $secp } } } $layer0Clone = Get-Variable -Name "$($layer[0])items" -ValueOnly if ($Pester.IsPresent) { [ValidationItem]::new( (Get-G2DPesterString -ConfigurationItem ($layer0Clone.RegistryItems + $layer0Clone.SecurityOptions + $layer0Clone.UserRightsAssignment + $layer0Clone.AuditPol) -ConfigurationName $exportName), $exportName, 'Pester' ) } [ValidationItem]::new( (Get-G2DDscConfigurationString -ConfigurationItem ($layer0Clone.RegistryItems + $layer0Clone.SecurityOptions + $layer0Clone.UserRightsAssignment + $layer0Clone.AuditPol) -ConfigurationName $exportName ), ($exportName -replace '\s'), 'Dsc' ) } } |