ExpandTemplate.ps1
<#
.SYNOPSIS Expands a template string with dynamically defined arguments. .DESCRIPTION The Expand-Template function uses PowerShell's built in string expansion functionality to populate the values of a parameterized string. This can be a string literal that is passed to the function, or the contents of an input file. .PARAMETER Template The template that will be expanded. This must be string literal so PowerShell does not preemptively expand the string. .PARAMETER InputFile An optional input file that contains the template. .PARAMETER OutputFile Ann optional output file path. When specified the expanded template will be written to this file. #> function Expand-Template { # IMPORTANT! # Do not mark this function with [CmdletBinding] or mark any parameters with [Parameter] # Doing so will break the dynamism of the unbound arguments. PowerShell gets angry and # throws exceptions because the unbound arguments exist. param ( [string] $Template, [string] $InputFile, [string] $OutputFile ) if ([string]::IsNullOrEmpty($Template)) { $Template = Get-Content -Path $InputFile -Raw } # IMPORTANT! # All variables except $Template are purposefully prefixed with double underscores # to prevent naming collisions with replacement variables in the value of $Template. $__argc = $MyInvocation.UnboundArguments.Count for ($__i = 0; $__i -lt $__argc; $__i++) { $__arg = [string]($MyInvocation.UnboundArguments[$__i]) # Variables have a leading dash if ($__arg.StartsWith('-')) { # Remove the leading dash $__arg = $__arg.Substring(1) # Get the next argument which is the value for __arg $__argv = $MyInvocation.UnboundArguments[$__i+1] # Create a new local variable New-Variable -Name $__arg -Value $__argv # Increment loop counter past the arg value $__i++ } } # Expand the variables in the template and return it to the caller. $Artifact = $ExecutionContext.InvokeCommand.ExpandString($Template) if (-not [string]::IsNullOrEmpty($OutputFile)) { # Write the content of file with a UTF8 BOM $Encoding = New-Object System.Text.UTF8Encoding($false) [System.IO.File]::WriteAllText($OutputFile, $Artifact, $Encoding) } else { $Artifact } } |