Working With Enums In PowerShell

Working With Enums In PowerShell

Enums are not a commonly used data type in PowerShell but after using them to force the TLS version that PowerShell would use in the previous blog post, I was reminded of how simple and useful this little used data type really is. Although they have been usable since PowerShell 1.0, they got some love in version 5.

What Is An Enum?

An enumerated type (called an enum for short) defines a set of values and restricts it’s use to those values. Each value is a member of the enum and each member has an associated integer value. The integer value is assigned to the member depending on the order in which it appears in the enum, starting with 0. You can override the integer value associated with a member.

A big advantage of an enum is that they improve code readability by allowing you to use friendly names to represent unfriendly numbers and restrict choices to those names.

Lets say you work for a company that has three departments - Finance, Engineering and Management. You create a script that restricts the operator to selecting one of those departments. What if your company adds a new department? All those code changes to add a new department selection in 10 or 20 different places within the script? Remember automation is about making your life easier, not more difficult!

If you declared the departments as an enum you would only need to add a new department to it for the operator to be able to select from it. One simple code change. Define the data in one place and reuse it.

Common PowerShell Enums

While you have been working with PowerShell you have been using enums without knowing it. One of the first enums most people come across is when they use Set-ExecutionPolicy and a member of the ExecutionPolicy enum to set it to.

PS> Get-Help Set-ExecutionPolicy -Parameter ExecutionPolicy

-ExecutionPolicy <ExecutionPolicy>
...


PS> [Microsoft.PowerShell.ExecutionPolicy]

IsPublic IsSerial Name                               BaseType
-------- -------- ----                               --------
True     True     ExecutionPolicy                    System.Enum


PS> [enum]::GetNames([Microsoft.PowerShell.ExecutionPolicy])
Unrestricted
RemoteSigned
AllSigned
Restricted
Default
Bypass
Undefined

Enclose a variable type in square brackets to retrieve information about it.

MSDN has documented the ExecutionPolicy enum.

Another common enum you probably didn’t know you were using is a parameter of the Set-Service cmdlet.

PS> Get-Help Set-Service -Parameter StartupType

-StartupType <ServiceStartMode>
...


PS> [System.ServiceProcess.ServiceStartMode]

IsPublic IsSerial Name                               BaseType
-------- -------- ----                               --------
True     True     ServiceStartMode                   System.Enum


PS> [enum]::GetNames([System.ServiceProcess.ServiceStartMode])
Boot
System
Automatic
Manual
Disabled

Accessing Enums In PowerShell

If you’ve ever used coloured output in PowerShell you are likely to do have done so using the Write-Host cmdlet with ForegroundColor or BackgroundColor parameters.

PS > Write-Host 'Darth is not Lukes father' ` 
    -ForegroundColor DarkBlue `
    -BackgroundColor White

The colours you pass to these parameters are in fact defined in an enum. If you use the help system for Write-Host you can find out where those values come from:

PS> Get-Help Write-Host -Parameter ForegroundColor

-ForegroundColor <ConsoleColor>
    Specifies the text color. There is no default. The acceptable
    values for this parameter are:

    - Black
    - DarkBlue
    - DarkGreen
    - DarkCyan
    ...

The parameter data type is <ConsoleColor> which is not one of PowerShell’s common data types we know such as Int, String or Boolean. We investigate further:

PS> [ConsoleColor]

IsPublic IsSerial Name                               BaseType
-------- -------- ----                               --------
True     True     ConsoleColor                       System.Enum

So now we know that it’s an enum, we can find it’s values in the usual way:

PS> [enum]::GetNames([ConsoleColor])

Black
DarkBlue
DarkGreen
DarkCyan
DarkRed
DarkMagenta
DarkYellow
Gray
DarkGray
Blue
Green
Cyan
Red
Magenta
Yellow
White

Which is the colours we expect. And it’s the colours we use for Write-Host ForegroundColor and BackgroundColor parameters.

Retrieving An Enum Member Number

We can retrieve the number values of each colour in the ConsoleColor enum by either casting them to [int] ([int][ConsoleColor]::Red) or using it’s value__ property (note the double underscores). We can even set the colour in Write-Host using the number instead of the colour’s name:

Working With Enums In PowerShell - ConsoleColor Internal Values

As we said earlier, the first member in an enum has the internal value of 0, so the first colour in ConsoleColor, Black, has the internal value of 0, the second colour, DarkBlue has the the internal value of 1 and so on.

Assigning Enum Values To Variables

Setting a variable using an enum is easily done.

PS> $myCol = [ConsoleColor]::Red


PS> $myCol
Red

But remember enums restrict the choices you can make.

PS> $myCol = [ConsoleColor]::Turquoise


PS> $myCol

As Turquoise is not a value from ConsoleColor you cannot do this but note that no error is thrown but the $myCol variable contains no value.

Feedback is always welcome. Drop me a comment below if this helped you or if you have used this on any other common PowerShell enums?