I’ve kicked the tires on a great PowerShell code scaffolding tool called ‘Plaster’. Here is my take on this nifty module.
If any PowerShell nut tells you that you should turn absolutely everything into a module then either they are expert level PowerShell users or idealistic (or maybe both!). In either case, it is easier said than done. I was struggling with the idea of turning my PSModuleBuild project into a module as it just doesn’t really fit the module mentality in what it does. PSModuleBuild is really a set of scripts and a directory structure that serve as a template for a build pipeline for PowerShell module projects. This project is not module in its own right though.
Fast forward a bit and I found a write up putting PSModuleBuild side by side with a project I’ve heard of previously called Plaster. This intrigued me and so I decided to give Plaster a whirl. What I found was an extremely flexible scaffolding framework with an almost unwieldy xml manifest file back end calling the shots.
The general idea of Plaster goes something like this: Each Plaster template is a directory with a plastermanifest.xml file that determines what input (parameters) is required to create the output (content) from the files in that directory.
That being said, it should not be surprising that A Plaster xml manifest file is broken down into three parts;
- General manifest details like author, version, and description
- Parameter elements that are prompted for or provided at the command line (via dynamic parameters)
- Content elements which are the directives for how the scaffold files are processed
While I can author xml with some level of proficiency, I thoroughly believe projects that tie themselves solely to xml suffer from a less robust adoption rate than those with simpler authoring methodologies. So in the spirit of open source I went ahead and submitted a pull request to add some functions to the project that pretty much take xml out of the picture. The functions are pretty simple and are able to be used separate from the module. As such I’m posting them here as well.
The gist of the additional functions is that you feed them arrays of hash tables that define either parameter or content elements. The parameter elements are exactly as you would expect, parameters to your Plaster manifest. They show up as prompts for data if you simply invoke the manifest with invoke-plaster. The content blocks are the rules that your plaster manifest follows after it has been fed all of the defined parameters. These content elements do various things like creating a new PowerShell module manifest files, copying files, displaying a message, or transforming files. And these all can get a bit messy if you are manually authoring them in xml.
The parameter elements are pretty simplistic and I was able to get away with using one function for creating these. The content elements are far more complicated so I decided to split them up into a function for each content type with a wrapper function for calling them.
Here is a quick example of creating two parameters, one prompting for a Nuget API key and another that prompts for a choice.
If you were to use this with the current version of Plaster you would have to create the plaster manifest with New-PlasterManifest then simply replace the ‘’ with the joined output of this function. The same goes for the content elements as well.
Note: I’ve submitted a pull request for including the content and parameter sections as part of the new-plastermanifest command. There is an ‘IncludeContent’ flag which is a bit different and includes xml files in the local directory in the content block (from what I could discern). Technically you could create the xml file manually for the content and then use this flag to include the content but I’ve not tested it out yet.
Currently there are a handful of supported content types. I’ve created a function for each of them and one big wrapper function for the lot of ’em so you can do fancy things like the following to create a bunch of content elements:
As with the parameter block creation you will need to manually replace the ‘’ xml with the joined output of this function.
The newModuleManifest content type in my helper function supports far more module manifest data than Plaster currently supports. I’ve put in a pull request for supporting the rest of the parameters that new-modulemanifest supports as well as supporting passing empty strings (which is nice if you want to create a new module manifest that doesn’t export every variable for instance).
I also have some changes that will directly accept parameter and content output from these functions in the new-plastermanifest command and am using all of this in my own project without any negative effects. But since they have not been approved/merged I’d not consider them official to the Plaster project in any way. As such, I’ve created another personal branch for this project that contains all my updates (as I wouldn’t have added them if I didn’t personally need them). You need only build it in vscode with CTRL+Shift+B (it is psake based) then use the module from the Releases directory.
Also the naming convention for the files in my repo is to follow that of the Plaster project.