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:
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?