PowerShell How-To

Using a Custom Enum To Get Tab-Completion on a Parameter

Sometimes using ValidateSet isn't enough -- for instance, when you have multiple functions with the same parameter that you need to perform a task on.

PowerShell has a data type called an enum, which is a way to set a variable for a number of predefined constants.

There are many useful features of enums in PowerShell, but the one that I've found I use the most is taking advantage of how they make function or script parameters behave when a parameter is explicitly cast as an enum.

When creating a function parameter in PowerShell, it's always good practice to assign that parameter a particular type, as shown below by casting both the Name and Type parameters as strings.

function New-Server {
    param(
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$Name,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$Type
    )

    ## Do stuff to create a server here
}

There are also times when you define a parameter and want to limit that parameter's value to a set of values. In the example above, perhaps I only want the Type parameter to be either Web, SQL or DomainController. PowerShell already has support for doing this kind of thing via the ValidateSet parameter attribute. This attribute not only prevents users from specifying different values from what you intended, but also has the added benefit of getting tab-completion for that parameter.

function New-Server {
    param(
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$Name,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [ValidateSet('Web','SQL','DomainController')]
        [string]$Type
    )

    ## Do stuff to create a server here
}

If you have this function in your PowerShell session, you can type the Type parameter, hit space and begin hitting the tab key. You'll see that PowerShell will cycle through all of the available options.

PS> New-Server -Name SRV1 -Type <HitTabKeyHere> 

This works great, but what if you have multiple functions with the same parameter that you'd like to perform this task on? If you were to use the ValidateSet parameter, you'd have to add that attribute to each and every one when it's the same every time. It'd be nice to define this attribute once and then use it on all functions. This can't be done with the ValidateSet attribute -- but it can be done by using an enum.

In PowerShell v5, we can define an enum by specifying the name of the enum and all of the constant values like below.

PS> enum ServerType {
Web
SQL
DoomainController
}

Once you have the enum available, you can then see all of the values that are available in the enum by what would normally be the method to check for static methods on a .NET object.

PS> [ServerType]::<HitTabHere>

Once it's created, you can then use this enum on as many parameters as you'd like by simply casting the parameter value to an enum, as shown below.

function New-Server {
    param(
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$Name,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [ServerType]$Type
    )

    ## Do stuff to create a server here
}

If you test out this function, you'll now see that we get the same tab-completion effect just as if we used the ValidateSet parameter attribute!

The beauty with using an enum to restrict parameter values and to get tab-completion is that I can now create as many functions as I like with the same parameter and "share" this feature, rather than having to define ValidateSet('val1,'val2','val3') every time I wish to use it.

About the Author

Adam Bertram is a 20-year veteran of IT. He's an automation engineer, blogger, consultant, freelance writer, Pluralsight course author and content marketing advisor to multiple technology companies. Adam also founded the popular TechSnips e-learning platform. He mainly focuses on DevOps, system management and automation technologies, as well as various cloud platforms mostly in the Microsoft space. He is a Microsoft Cloud and Datacenter Management MVP who absorbs knowledge from the IT field and explains it in an easy-to-understand fashion. Catch up on Adam's articles at adamtheautomator.com, connect on LinkedIn or follow him on Twitter at @adbertram or the TechSnips Twitter account @techsnips_io.


comments powered by Disqus
Most   Popular