PowerShell Script Module Design: Public/Private versus Functions/Internal folders for Functions

There’s been a lot of debate about script module design as of lately and instead of tweeting something out asking for responses, I thought I would post it here via a blog article.

Back when I first started creating PowerShell script modules, I placed all of my functions in the PSM1 file and later started placing each function in a separate PS1 file that was dot-sourced from the PSM1 file.

#Dot source all functions in all ps1 files located in the module folder
Get-ChildItem -Path $PSScriptRoot\*.ps1 -Exclude *.tests.ps1, *profile.ps1 |
ForEach-Object {
. $_.FullName
}

I would simply place the PS1 files in the root folder of the script module. Later, when I started writing functions that I didn’t want to make public, I created a folder named Private and placed the private functions in that folder.

I’ve recently updated my Plaster template for creating script modules and decided to place the PS1 files for the public functions in a sub-folder instead of in the module’s root folder. The dilemma is whether those should be called Public and Private or Functions and Internal. I see a lot of both options from others in the PowerShell community.

At this point, I’m leaning towards using Functions and Internal for the folder names because to me it’s more declarative for someone who may not understand what’s going on and when you start adding things like Classes into their own sub-folder, it only seems to make more sense.

This blog article isn’t some rant about whether or not you should place your functions into separate PS1 files or in the PSM1 file. Moving forward, I plan to have functions in separate files for development which is what you’ll find in my GitHub repositories. I plan to use a build process to merge all of the functions from the separate PS1 files back into the PSM1 file for production and that’s what you’ll find me publishing on the PowerShell Gallery. This module creation process will give me the best of both worlds. Separate functions while in development to avoid things like merge conflicts and if someone wants just one of my functions and not the entire module, they can simply download it from GitHub. The module will be packaged up for use in a production environment and if you install it from the PowerShell Gallery, that’s what you’ll get. This will eliminate things like slowness when the module is loaded due to the functions being in separate PS1 files. It will also be a lot simpler to sign fewer files before I publish them to the PowerShell gallery.

Did you know that one of the best practices for publishing your modules to the PowerShell Gallery is to sign them?

I’ve created a list on Twitter of the community members that I’ve seen building and promoting PowerShell script modules using similar designs. If I’ve missed someone, please post a link to their script module design content as a reply to this blog article.

I’d love to hear your thoughts or suggestions on the public/private versus functions/internal naming scheme debate. Please post them as a reply to this blog article.


Update based on Twitter responses.

What I’m hearing so far based on the responses on Twitter is Public/Private seems to be more widely accepted by the community. I’ll probably end up using those since that’s the whole point of this blog article (standardization).

ยต