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
Another common enum you probably didn’t know you were using is a parameter of the
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
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
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
Retrieving An Enum Member Number
We can retrieve the number values of each colour in the
ConsoleColor enum by either casting them to
[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
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
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?