functions/Split-PsLaArmTemplate.ps1
<# .SYNOPSIS Split an ARM template into multiple files, based on the resource type .DESCRIPTION You might have a large ARM template, consisting of multiple resource types. This script will create single ARM templates for the specified resource type, and will copy the parameters from the original template .PARAMETER Path Path to the ARM template that you want to work against .PARAMETER OutputPath Path to were the ARM template file will be persisted The path has to be a directory The file will be named as the original ARM template file .PARAMETER TypeFilter Instruct the cmdlet to only process the specified resource type The default value is 'Microsoft.Web/connections' .EXAMPLE PS C:\> Split-ArmTemplate -Path 'C:\temp\template.json' -OutputPath 'C:\temp\output' This will create a new ARM template file for each resource of the type 'Microsoft.Web/connections' in the original ARM template file. The new ARM template files will be persisted in the 'C:\temp\output' directory. .EXAMPLE PS C:\> Split-ArmTemplate -Path 'C:\temp\template.json' This will create a new ARM template file for each resource of the type 'Microsoft.Web/connections' in the original ARM template file. The new ARM template files will be persisted in the same directory as the original ARM template file. .EXAMPLE PS C:\> Split-ArmTemplate -Path 'C:\temp\template.json' -TypeFilter 'Microsoft.Web/sites' This will create a new ARM template file for each resource of the type 'Microsoft.Web/sites' in the original ARM template file. The new ARM template files will be persisted in the same directory as the original ARM template file. .NOTES Author: Mötz Jensen (@Splaxi) #> function Split-PsLaArmTemplate { [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseOutputTypeCorrectly', '')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '')] [CmdletBinding()] param ( [parameter(Mandatory = $true)] [PsfValidateScript('PSFramework.Validate.FSPath.File', ErrorString = 'PSFramework.Validate.FSPath.File')] [Alias('File')] [string] $Path, [PsfValidateScript('PSFramework.Validate.FSPath.Folder', ErrorString = 'PSFramework.Validate.FSPath.Folder')] [string] $OutputPath, [Alias('ResourceType')] [string] $TypeFilter = 'Microsoft.Web/connections' ) if (-not $OutputPath) { $OutputPath = Split-Path -Path $Path -Parent } # #Make sure the output path is created and available New-Item -Path $OutputPath -ItemType Directory -Force -ErrorAction Ignore > $null #The task counter needs to be reset prior running Set-PSFConfig -FullName PsLogicAppExtractor.Execution.TaskCounter -Value 0 Set-PSFConfig -FullName PsLogicAppExtractor.Execution.TaskInputNext -Value "" Set-PSFConfig -FullName PsLogicAppExtractor.Execution.TaskOutputFile -Value "" Set-PSFConfig -FullName PsLogicAppExtractor.Execution.TaskPath -Value "" Set-PSFConfig -FullName PsLogicAppExtractor.Execution.Name -Value "" $InputObject = Get-TaskWorkObject -Path $Path # We only want to process the resources that are of the type we are looking for $colFiltered = $InputObject.resources | Where-Object { $_.type -eq $TypeFilter } $baseName = Split-Path -Path $Path -LeafBase for ($i = 0; $i -lt $colFiltered.Count; $i++) { $Destination = Join-Path -Path $OutputPath -ChildPath "$baseName`__$(($i+1).ToString().PadLeft(3, "0")).json" $obj = $colFiltered[$i] # Loading the original ARM template file, but to be used for the local resource $tempArm = Get-TaskWorkObject -Path $Path # The resources is overwritten with the resource we are currently processing $tempArm.resources = @($obj) # We need to do some string manipulation to get the names of the parameters $jsonStr = $obj | ConvertTo-Json -Depth 100 # We need to match all parameters that are used in the resource $parmsToKeep = @(($jsonStr | Select-String "parameters\('(.*?)'\)" -AllMatches).Matches.Groups | Where-Object { $null -eq $_.Groups } | Select-Object -ExpandProperty Value -Unique) # We need to remove all parameters that are not used in the resource $tempArm.Parameters.PsObject.Properties | Where-Object { $parmsToKeep -notcontains $_.Name } | Select-Object -ExpandProperty Name | ForEach-Object { $tempArm = Remove-ArmParameter -InputObject $tempArm -Name $_ } Out-TaskFile -Path $Destination -InputObject $tempArm } } |