Lightweight PowerShell Templating Engine

<#

.SYNOPSIS

Expand-Template.ps1

Simple templating engine to expand a given template text containing PowerShell expressions.

.PARAMETER Text

The text of the template to do the expansion

.PARAMETER Path

Path to template to do the expansion

.PARAMETER Desitination

Destination path to write expansion result.  If not specified, write to output stream.

.PARAMETER PsConfigurationPath                          

Path to file containing PowerShell code. This file could contain variable values to use when evaluating templates

.PARAMETER BeginTag

Begin tag for detecting expand expression in template

.PARAMETER EndTag

End tag for detecting expand expression in template

.EXAMPLE

$message=”hello”; .\Expand-Template.ps1 -Text ‘I would like to say [[$message]] to the world’

#>

[CmdletBinding()]

param

(

    [Parameter(Mandatory=$true, ParameterSetName=‘Text’,ValueFromPipeline=$true)]

    [string]$Text,

    [Parameter(Mandatory=$true, ParameterSetName=‘Path’)]

    [string]$Path,

    [string]$Destination,

    [string]$PsConfigurationPath,

    [string]$BeginTag = ‘[[‘,

    [string]$EndTag = ‘]]’

)

$BeginTag = [RegEx]::Escape($BeginTag)

$EndTag = [RegEx]::Escape($EndTag)

Write-Verbose ‘Expand-Template’

if ($Path) {

    if (!(Test-Path -Path $path)) { throw “Template-Expand: path `’$path`’ can’t be found”  }

    $Text = Get-Content -Path $path -Raw

}

if ($PsConfigurationPath) {

    if (!(Test-Path -Path $PsConfigurationPath)) { throw “Template-Expand: psConfigurationPath `’$psConfigurationPath`’ can’t be found” }

    Write-Verbose ” ** Loading PS Configuration file: $PsConfigurationPath

    . $PsConfigurationPath

}

$pattern = New-Object -Type System.Text.RegularExpressions.Regex `

                      -ArgumentList $BeginTag(.*?)$EndTag,([System.Text.RegularExpressions.RegexOptions]::Singleline)

$matchEvaluatorDelegate =  [System.Text.RegularExpressions.MatchEvaluator] {

           param([System.Text.RegularExpressions.Match]$Match)

           $expression = $match.get_Groups()[1].Value # content between markers

           Write-Verbose ”  ** expanding expression: $expression

           trap { Write-Error “Failed to expand template. Can’t evaluate expression ‘$expression‘. The following error occured: $_; break }

           Invoke-Expression -command $expression | Tee-Object -Variable result

           Write-Verbose ”  ** expanded expression evaluated value:`n$result`n”

    }

$expandedText = $pattern.Replace($text, $matchEvaluatorDelegate)

if (-not $destination){ $expandedText }

else { Set-Content -Path $destination -value $expandedText -encoding $Encoding }