Template for sharing parameter definitions for many functions

I am creating a PowerShell module with many different functions that share a common set of parameters. With all the parameter metadata, these functions become quite complex to manage. One small parameter change, adding a new parameter, or removing a parameter means I have to update a bunch of different function files.

Besides templating code / code-gen, does anyone have a recommended template for sharing parameter definition blocks across many functions in PowerShell?

+3


source to share


2 answers


I can feel your pain. I've encountered this many times. Unfortunately, there isn't a big, native PowerShell solution that solves all of this. Several possible options:

Write tests

Simple: use Pester, write tests. It won't help you reduce the amount of copy / paste you have to do, or re-enter the same parameter blocks, but what it does is make sure that if you change a parameter in one place and forget to change it somewhere else, or make an incompatible change, the tests will fail.

Of course, this means that you should write tests in a way that breaks these problems, but you should still be.

I still don't write tests nearly as often as I should, but I think this option provides the best overall result, although it has a high level of input noise.

Use strongly typed custom classes for Params

At some point, you might realize that a group of parameters should be passed all over the place, and indeed, these parameters describe various aspects (properties) of a particular unit or concept (class).

You will understand that this is the case when you begin to understand that the parameters depend on each other (more than you describe in the parameter set), so you can start writing a validation for it and realize that it becomes very difficult.

The solution is that these parameters should be properties of the class, so the class takes care of checking the values ​​and relationships between properties.



This becomes especially obvious and important if you realize that you have more than one of these "groups" in your parameters and you need multiple objects. Parameter set writing and validation becomes exponentially more complex with more than one of them, and breaking them up into classes will make that easier.

disadvantages

Writing classes in PowerShell sucks. Also, there is no good way to export a class defined in a PowerShell module, which means your functions are aware of this, but the consumer of the module is not.

This, in turn, means that you cannot use a class as a parameter to a public function. There are explicit ways to export it, so you can do that, but ...

As an alternative

Write the classes in C #. You don't need to do anything with the assembly (.dll) to use it in PowerShell as long as the class is public. Import-Module

just works.

But, of course, this is a completely different development pipeline, build process, distribution process, etc.

Templating / Code-gen

You touched it, but ... seriously, don't do it.

+4


source


If functions share many parameters, I suspect they have a lot of code in common. If so, I would consider the following approach I used for the registration framework, which includes features like Log-Entry

, Log-Debug

and Log-Verbose

:

  • Create one main function (in my case Log-Entry

    )
  • Create aliases for each add function (in my case Log-Debug

    and Log-Verbose

    )
  • Disable functionality by checking the function name using $MyInvocation.InvocationName



how

Function Log-Entry {
<#
.Synopsis
    Log-Entry
.Description
    Displays and records cmdlet processing details in a file
#>
Param(
    ...
)
    ...
    If ($MyInvocation.InvocationName -eq "Log-Debug") {
        ...
    }
    If ($MyInvocation.InvocationName -eq "Log-Verbose") {
        ...
    }
    ...
}
Set-Alias Log-Debug    Log-Entry -Description "By default, the Log-Debug entry is not displayed and not recorded, but you can display it by changing the common -Debug parameter."
Set-Alias Log-Verbose  Log-Entry -Description "By default, the Log-Verbose entry is not displayed, but you can display it by changing the common -Verbose parameter."

      

0


source







All Articles