Creating a Module Manifest for the PowerShell Gallery and NuGet

One of my self-assigned special projects has been working on a PowerShell module for Rubrik, because I really dig PowerShell. Plus, it’s a great learning experience. And part of that has been dealing with how to best build a Module Manifest (psd1 file) and Script Manifest (psm1 file).

Traditionally, I was taught to bake all of the required functions into the Script Manifest and use Export-ModuleMember. But this is a bit of sad panda because there’s now a single file that contains dozens of functions. It’s hard to work on the file with a team. So, I split each function into its own script file using the proper Verb-Noun naming format required by PowerShell standards.

script-files

I’d then point the Module Manifest’s RootModule variable to a Script Module that simply combed through a folder and dot-sourced all of the ps1 (PowerShell script files) it could find. This was accomplished with a one-liner:

gci $psscriptroot\*.ps1 | % { . $_.FullName }

Additionally, the Module Manifest’s FunctionsToExport variable was set to a global wildcard using an asterisk.

psd1-export

Easy, right? By loading the module, the net result is that all of the functions would get loaded as commands associated with the module. It required little effort to maintain, as the only variables I had to update were the ModuleVersion and some of the note fields.

Woes with Update-ModuleManifest

After several dozen commits, I decided to get a little fancy and try using the Update-ModuleManifest cmdlet to perform updates. The issue is that this cmdlet is terrible and loves to mangle the Module Manifest. It constantly changed my wildcard asterisk to an empty array, thus breaking the manifest and resulting in no functions being exported. I had other issues with it, such as changing an array of strings into a long string in the FunctionsToExport variable. Crazy!

I would advise running it just once – or using a New-ModuleManifest cmdlet – to seed a clean and updated manifest with PowerShell 5.0 (part of Windows 10 or WMF 5.0). Why? Because there’s a new section stored in the array named PrivateData that contains helpful metadata required for the PowerShell Gallery, and it’s good to have an updated manifest.

private-data

This information is revealed in the PowerShell Gallery, which works along side NuGet, making publishing with Publish-Module a snap.

rubrik-1003

But, wait – where are my functions?

Exposing Functions to the PowerShell Gallery and NuGet

It seems that the issue is my use of a wildcard asterisk for the FunctionsToExport variable. Not only does it break the auto-loading capabilities of PowerShell, in which a function is loaded on-demand when called (even if the module isn’t imported), but it prevents the NuGet process from listing out my functions.

The answer is pretty straight forward: explicitly list the functions to export using an array of strings that match the name of the script files. Note that ISESteroids is allowing me to do word wrap in the PowerShell ISE. 🙂

export-list

The result is a list of functions now appears in the PowerShell gallery.

functions-visible

Additionally, the functions will now load the module just by calling them. In the example below, I show that the Rubrik module is not imported. However, using the Connect-Rubrik function (and then escaping from it) shows the Rubrik module is now loaded. Handy!

load-module-auto

If you want to look at any of the module or script manifests, you can find them in my GitHub repository here.