{"id":14063854,"url":"https://github.com/straightdave/eps","last_synced_at":"2026-02-08T06:10:30.208Z","repository":{"id":16856853,"uuid":"19616873","full_name":"straightdave/eps","owner":"straightdave","description":"A templating engine for PowerShell","archived":false,"fork":false,"pushed_at":"2019-06-14T08:44:23.000Z","size":200,"stargazers_count":153,"open_issues_count":10,"forks_count":22,"subscribers_count":12,"default_branch":"master","last_synced_at":"2024-08-13T07:05:36.794Z","etag":null,"topics":["powershell","template-engine"],"latest_commit_sha":null,"homepage":"http://straightdave.github.io/eps/","language":"PowerShell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/straightdave.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-05-09T16:01:22.000Z","updated_at":"2024-06-21T21:08:26.000Z","dependencies_parsed_at":"2022-07-08T06:50:20.743Z","dependency_job_id":null,"html_url":"https://github.com/straightdave/eps","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/straightdave%2Feps","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/straightdave%2Feps/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/straightdave%2Feps/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/straightdave%2Feps/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/straightdave","download_url":"https://codeload.github.com/straightdave/eps/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228032913,"owners_count":17858914,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["powershell","template-engine"],"created_at":"2024-08-13T07:03:32.380Z","updated_at":"2026-02-08T06:10:30.152Z","avatar_url":"https://github.com/straightdave.png","language":"PowerShell","funding_links":[],"categories":["PowerShell"],"sub_categories":[],"readme":"[![Build status](https://ci.appveyor.com/api/projects/status/dkkgi7fg8fsubqph?svg=true)](https://ci.appveyor.com/project/dbroeglin/eps)\n\n# EPS\n\nEPS ( *Embedded PowerShell* ), inspired by [ERB][erb], is a templating tool that embeds\nPowerShell code into a text document. It is conceptually and syntactically similar to ERB\nfor Ruby or [Twig][twig] for PHP.\n\nEPS can be used to generate any kind of text. The example below illustrates generating\nplain text, but it could be used to generate HTML as in [DS][ds] or PowerShell code as\nin the [Forge Module generator][forge_module].\n\nEPS is available in the [PowerShell Gallary](https://www.powershellgallery.com/packages/EPS).\nYou can install the module with the following command:\n\n```powershell\nInstall-Module -Name EPS\n```\n\n## Syntax\n\nEPS allows PowerShell code to be embedded within a pair of `\u003c% ... %\u003e`,\n`\u003c%= ... %\u003e`, or `\u003c%# ... %\u003e` as well:\n\n- Code in `\u003c% CODE %\u003e` blocks are executed but no value is inserted.\n  - If started with `\u003c%-` : the preceding indentation is trimmed.\n  - If terminated with `-%\u003e` : the following line break is trimmed.\n- Code in `\u003c%= EXPRESSION %\u003e` blocks insert the value of `EXPRESSION`.\n  - If terminated with `-%\u003e` : the following line break is trimmed.\n- Text in `\u003c%# ... %\u003e` blocks are treated as comments and are removed from the output.\n  - If terminated with `-%\u003e` : the following line break is trimmed.\n- `\u003c%%` and `%%\u003e` : are replaced respectively by `\u003c%` and `%\u003e` in the output.\n\nAll blocks accept multi-line content as long as it is valid PowerShell.\n\n## Command Line Usage\n\n```PowerShell\nInvoke-EpsTemplate [-Template \u003cstring\u003e] [-Binding \u003chashtable\u003e] [-Safe]  [\u003cCommonParameters\u003e]\n\nInvoke-EpsTemplate [-Path \u003cstring\u003e] [-Binding \u003chashtable\u003e] [-Safe]  [\u003cCommonParameters\u003e]\n```\n\n- use `-Template` to render the template in the corresponding string.\nthan a file\n- use `-Path` to render the template in the corresponding file.\n- `-Safe` renders the template in **isolated** mode (in another thread/powershell\ninstance) to avoid variable pollution (variable that are already in the current\nscope).\n- if `-Safe` is provided, you must bind your values using `-Binding` option\nwith a `Hashtable` containing key/value pairs.\n\n## Example\n\nA very simple example of EPS would be :\n\n```powershell\n$name = \"Dave\"\n\nInvoke-EpsTemplate -Template 'Hello \u003c%= $name %\u003e!'\n```\n\nThis script produces the following result:\n\n```\nHello Dave!\n```\n\nIn a template file `Test.eps`:\n\n```\nHi \u003c%= $name %\u003e\n\n\u003c%# this is a comment -%\u003e\nPlease buy me the following items:\n\u003c% 1..5 | %{ -%\u003e\n  - \u003c%= $_ %\u003e pigs ...\n\u003c% } -%\u003e\n\nDave is a \u003c% if($True) { %\u003eboy\u003c% } else { %\u003egirl\u003c% } %\u003e.\n\nThanks,\nDave\n\u003c%= (Get-Date -f yyyy-MM-dd) %\u003e\n```\n\nThen render it in on the command line:\n```powershell\nImport-Module EPS\n\n$name = \"ABC\"\nInvoke-EpsTemplate -Path Test.eps\n```\n\nHere it is in non-safe mode (render template with values in current run space)\nTo use safe mode (render the template in an isolated scope) execute: `Invoke-EpsTemplate -Path Test.eps -Safe` with binding values\n\nIt will produce:\n\n```\nHi dave\n\nPlease buy me the following items:\n  - 1 pigs ...\n  - 2 pigs ...\n  - 3 pigs ...\n  - 4 pigs ...\n  - 5 pigs ...\n\nDave is a boy.\n\nThanks,\nDave\n2016-12-07\n```\n\nOr you can use safe mode with data bindings:\n```powershell\nInvoke-EpsTemplate -Path Test.eps -Safe -binding @{ name = \"dave\" }\n```\n\nwhich will generate the same output.\n\n## More examples\n\n### Multi-line code or expression blocks\n\nYou can use multi-line statements in blocks:\n\n```powershell\n$name = \"Dave\"\n\nInvoke-EpsTemplate -Template @'\nHello \u003c%= $name %\u003e!\nToday is \u003c%= Get-Date -UFormat %x %\u003e.\n'@\n```\n\nwill produce:\n\n```\nHello Dave!\nToday is 11/12/17.\n```\n\n### Iterating and joining the results\n\nSometimes we would like to iterate over a collection, generate some text for each\nelement and finally join the generated blocks together with a separator.\n\n#### Inside expression blocks\n\nIn an expression block we can use the following idiomatic PowerShell snippet:\n\n```powershell\nInvoke-EpsTemplate -Template @'\n\u003c%= (\"Id\", \"Name\", \"Description\" | ForEach-Object { \"[String]`$$_\" }) -Join \",`n\" -%\u003e\n'@\n```\nwhich would generate the following result:\n\n```powershell\n[String]$Id,\n[String]$Name,\n[String]$Description\n```\n#### With EPS templating elements\n\nHowever, due to EPS internal workings, the following code would not work:\n\n```powershell\nInvoke-EpsTemplate -Template @'\n\u003c% (\"Id\", \"Name\", \"Description\" | ForEach-Object { -%\u003e\n[String]$\u003c%= $_ -%\u003e\n\u003c% }) -join \",`n\" -%\u003e\n'@\n```\n\nThe `-join` operator is ignored by EPS:\n\n```\n[String]$Id[String]$Name[String]$Description\n```\n\nThis is expected behavior because `-join` is applied to the result of \n`ForEach-Object` which is defined inside a _CODE_ block and should not produce\nany output.\n\nEPS provides an internal `Each` function whose behavior is similar to \n`ForEach-Object` but achieves the desired result inside a template :\n\n```PowerShell\nEach [-Process] \u003cscriptblock\u003e [-InputObject \u003cObject[]\u003e] [-Begin \u003cscriptblock\u003e] [-End \u003cscriptblock\u003e] [-Join \u003cstring\u003e]\n```\n\n`Each` can only be used in PS v3 or above.\n\nThis snippet of EPS would generate the desired result (notice that `-Join` is a parameter of `Each`\nand is not applied to its result value as would be the case with the `-join` operator):\n\n```powershell\nInvoke-EpsTemplate -Template @'\n\u003c% \"Id\", \"Name\", \"Description\" | Each { -%\u003e\n[String]$\u003c%= $_ -%\u003e\n\u003c% } -Join \",`n\" -%\u003e\n'@\n```\n\nand generate:\n\n```powershell\n[String]$Id,\n[String]$Name,\n[String]$Description\n```\n\nIn some cases it can be useful to also generate a prefix and suffix to the iterated part:\n\n```powershell\nInvoke-EpsTemplate -Template @'\n\u003c% \"Id\", \"Name\", \"Description\" | Each { -%\u003e\n[String]$\u003c%= $_ -%\u003e\n\u003c% } -Begin { %\u003e[NSSession]$Session\u003c% } -End { %\u003e[String]$LogLevel\u003c% } -Join \",`n\" -%\u003e\n'@\n```\n\nwill generate:\n\n```powershell\n[NSSession]$Session,\n[String]$Id,\n[String]$Name,\n[String]$Description,\n[String]$LogLevel\n```\n\nNotice that when using `-Begin` and/or `-End` with `-Join` all blocks are joined together.\n\nIf you want to prefix and suffix, _without_ joining the prefix and suffix, use the following\npattern:\n\n```powershell\nInvoke-EpsTemplate -Template @'\nParam(\n\u003c% \"Id\", \"Name\", \"Description\" | Each { -%\u003e\n    [String]$\u003c%= $_ -%\u003e\n\u003c% } -Join \",`n\" %\u003e\n)\n'@\n```\n\nWhich will generate:\n\n```powershell\nParam(\n    [String]$Id,\n    [String]$Name,\n    [String]$Description\n)\n```\n\n### Iterating with an index\n\nIn some cases it is useful to iterate over a collection while maintaining an _index_ of the\ncurrent item. The `Each` function exposes a `$index` variable to the script blocks it executes.\nThe `$index` variable starts at 0 for the first element.\n\n```powershell\nInvoke-EpsTemplate -Template @'\n\u003c% \"Dave\", \"Bob\", \"Alice\" | Each { -%\u003e\n\u003c%= $Index + 1 %\u003e. \u003c%= $_ %\u003e\n\u003c% } -%\u003e\n'@\n```\n\nwould generate the following listing:\n\n```\n1. Dave\n2. Bob\n3. Alice\n```\n\n### Handling default values\n\nUsing default values if the provided variable is `$Null` or empty (as returned by the `[string]::IsNullOrEmpty` function) is a very common pattern which can be done easily with a template like:\n\n```powershell\n$config = [PSCustomObject]@{\n  Host = \"localhost\"\n  #Port = \"8080\" # this would be an optional configuration value\n}\nInvoke-EpsTemplate -Template @'\n\u003c%= $config.Host \n%\u003e:\u003c%= \n  if ([string]::IsNullOrEmpty($config.Port)) { \"80\" } else { $config.Port }\n%\u003e\n'@\n```\n\nEPS provides a `Get-OrElse` function that allows for a shorter version:\n\n```powershell\n$config = [PSCustomObject]@{\n  Host = \"localhost\"\n  #Port = \"8080\" # this would be an optional configuration value\n}\nInvoke-EpsTemplate -Template @'\n\u003c%= $config.Host %\u003e:\u003c%= Get-OrElse $config.Port \"80\" %\u003e\n\u003c%= $config.Host %\u003e:\u003c%=  $config.Port | Get-OrElse -Default \"80\" %\u003e\n'@\n```\n\n### Helper functions\n\nIf there's a more complicated piece of powershell code that should be reused across multiple files, it can be encapsulated in a helper function, i.e.:\n\n```powershell\n$helpers = @{\n   NumberedList = { \n     param($arr)\n     $i = 1\n     $arr | foreach-object { \"$i. $_\"; $i++ } | out-string \n  }\n}\n```\n\n`$helpers` should be passed to `Invoke-Eps`:\n\n```\nInvoke-EpsTemplate -Path Test.eps -helpers $helpers\n```\n\nNow, `NumberedList` can be used in the template.\n\n```powershell\n\u003c%= NumberedList \"Dave\", \"Bob\", \"Alice\" %\u003e\n```\n\nwould generate the following listing:\n\n```\n1. Dave\n2. Bob\n3. Alice\n\n```\n\n## Contribution\n\n* Original version was written by [Dave Wu](https://github.com/straightdave).\n* Maintained now and extended by [Dominique Broeglin (@dbroeglin)](https://github.com/dbroeglin), thank you pal 谢谢！\n\nHelp find more bugs! Or find more usage of this tool...\nAuthor's email: eyaswoo@163.com\n\n[erb]: https://en.wikipedia.org/wiki/ERuby\n[twig]: http://twig.sensiolabs.org/\n[ds]: https://github.com/straightdave/ds\n[forge_module]: https://github.com/dbroeglin/Forge.Module\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstraightdave%2Feps","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstraightdave%2Feps","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstraightdave%2Feps/lists"}