functions/Update-HydrationDefinitionFolderStructureByAssignment.ps1
<#
.SYNOPSIS The Update-HydrationDefinitionFolderStructureByAssignment function processes policy set definitions and policy definitions from a specified directory, moves them based on their assignments, and logs the changes. .DESCRIPTION This function adds a folder layer at the ./Definitions/policySetDefinitions and ./Definitions/policyDefinitions folder layers based on the ./Definitions/policyAssignments subdirectory structure. Each definition will be copied to an output structure to reflect the structure used in assignments. This is to assist with security structure, such as use of GitHub Code Owners. If a definition is not assigned, either directly or via a policySetDefinition, it will be placed in the root of the Unused subfolder. This will assist with cleanup and organization. .PARAMETER Definitions The path to the directory containing the policy set definitions and policy definitions. The default is "./Definitions". .PARAMETER Output The path to the directory where the output will be saved. The default is "./Output". .PARAMETER FolderOrder An ordered hashtable specifying the order of the folders. .EXAMPLE $myFolderOder = [ordered]@{ SecurityOperations = "security" HRProtected = "hr" FinanceTracking = "finance" PlatformOperations = "platform" } Update-HydrationDefinitionFolderStructureByAssignment -Definitions "./Definitions" -Output "./Output" -FolderOrder $myFolderOrder .LINK https://aka.ms/epac https://github.com/Azure/enterprise-azure-policy-as-code/tree/main/Docs/start-hydration-kit.md #> function Update-HydrationDefinitionFolderStructureByAssignment { param ( [Parameter(Mandatory = $false, HelpMessage = "The path to the directory containing the policy set definitions and policy definitions. The default is './Definitions'.")] [string] $Definitions = "./Definitions", [Parameter(Mandatory = $false, HelpMessage = "The path to the directory where the output will be saved. The default is './Output'.")] [string] $Output = "./Output", [Parameter(Mandatory = $true, HelpMessage = "An ordered hashtable specifying the order of the folders.")] [System.Management.Automation.OrderedHashtable] $FolderOrder ) $InformationPreference = "Continue" # TODO: Add a reporting feature to use the keys for Folder Order as organization internal values that tie to the approval folders in GitHub Owners for output logs. $psdList = Get-ChildItem $(Join-Path $Definitions "policySetDefinitions") -recurse -file -include "*.json", "*.jsonc" $pdList = Get-ChildItem $(Join-Path $Definitions "policyDefinitions") -recurse -file -include "*.json", "*.jsonc" Write-Debug "Policy Set Definition Count: $($psdList.Count)" Write-Debug "Policy Set Count: $($pdList.Count)" $ChangeLogData = [ordered]@{ } Write-Information "Processing $($psdList.Count) Policy Set Definitions..." foreach ($psd in $psdList) { Write-Debug "Processing $($psd.Name)..." $outInfo = Copy-DefinitionByAssignment -PolicyPath $psd.FullName -FolderOrder $FolderOrder -Definitions $Definitions -Output $Output -ChangeLogData:$ChangeLogData if ($outInfo) { $ChangeLogData.Add($psd.FullName, $outInfo) } else { Write-Warning " No return from Move-DefinitionByPolicyAssignment for $($psd.Name)" } } $psdProcessedCount = $ChangeLogData.Keys.Count Write-Information "Classified $psdProcessedCount Policy Set Definitions..." $newPsdFolder = @{ Path = $Output ChildPath = "NewFolderStructure" AdditionalChildPath = "policySetDefinitions" } $newPsdPath = Join-Path @newPsdFolder $newPsdList = Get-ChildItem $newPsdPath -recurse -file -include "*.json", "*.jsonc" Write-Information "$newPsdPath File Count: $($newPsdList.Count)" ## Begin Processing Policy Definitions Write-Information "Processing $($pdList.Count) Policy Definitions..." foreach ($pd in $pdList) { Write-Debug "Processing $($pd.Name)..." $outInfo = Copy-DefinitionByAssignment -PolicyPath $pd.FullName -FolderOrder $FolderOrder -Definitions $Definitions -Output $Output -ChangeLogData:$ChangeLogData if ($outInfo) { $ChangeLogData.Add($pd.FullName, $outInfo) } else { Write-Warning " No return from Move-DefinitionByPolicyAssignment for $($pd.Name)" } } $pdProcessedCount = $ChangeLogData.Keys.Count - $psdProcessedCount Write-Information "Classified $pdProcessedCount Policy Set Definitions..." $newPdFolder = @{ Path = $Output ChildPath = "NewFolderStructure" AdditionalChildPath = "policyDefinitions" } $newPdPath = Join-Path @newPdFolder $newPdList = Get-ChildItem $newPdPath -recurse -file -include "*.json", "*.jsonc" Write-Information "$newPdPath File Count: $($newPdList.Count)" $outputFile = @{ Path = $Output ChildPath = "NewFolderStructure" AdditionalChildPath = "ChangeLog.json" } $outputFilePath = Join-Path @outputFile if (!(Test-Path $(Split-Path $outputFilePath))) { $null = New-Item -Path $(Split-Path $outputFilePath) -ItemType Directory -Force } $ChangeLogData | Export-HydrationObjectToJsonFile -OutputFilePath $outputFilePath if (Test-Path $outputFilePath) { Write-Information "Change Log saved to $outputFilePath" } else { Write-Warning "Failed to create log at $outputFilePath" } } |