More Fun with PowerShell Enums

Introduction

In a previous post, Fun with PowerShell Enums I introduced the concept of Enums.

In this post we’ll dive deeper into enums, taking a look at more of its properties a well as other ways to use enums.

First let me mention that for all of the examples we’ll display the code, then under it the result of our code. In this article I’ll be using PowerShell Core, 7.2, and VSCode. The examples should work in PowerShell 5.1 in the PowerShell IDE, although they’ve not been tested there.

To run a snippet of code highlight the lines you want to execute, then in VSCode press F8 or in the IDE F5. You can display the contents of any variable by highlighting it and using F8/F5.

Enums for Code Clarity

One major way enums can be used is to clarify your code. In my previous post on enums I mentioned I was a ham radio operator. The clubs I belong to meet on alternate Thursday nights. Let’s say I wrote a small PowerShell function to let me know if tonight is a ham club meeting.

Into that function I need to pass one parameter, a number that indicates the day of the week. If 0 is Sunday, and 6 Saturday, the number 4 represents a Thursday.

function IsItHamClubNight($Day)
{
  if ($Day -eq 4)
  { Write-Host "Yay! It's ham club night" }
  else 
  { Write-Host "Sorry, just a boring night" }
}

When I call this function, I have to know what number to use.

$day = 4
IsItHamClubNight $day

Result:

Yay! It's ham club night

Obviously it would be easier to pass in the name of the day of the week rather than a number. But this function is now heavily embedded in your organization, changing it would require a large effort.

By using an enum, we can provide the ability to use a human readable name, without the need to rewrite our function.

Enum DaysOfWeek
{
  Sunday = 0
  Monday = 1
  Tuesday = 2
  Wednesday = 3
  Thursday = 4
  Friday = 5
  Saturday = 6
}

Enums allow us to assign a value to each label. Here we made Sunday 0, and so on, but we can use any integer value. Now we can assign one of the enums to a variable and pass that into our function.

$day = [DaysOfWeek]::Thursday
IsItHamClubNight $day

Result:

Yay! It's ham club night

Even better, we can skip the use of a variable.

IsItHamClubNight ([DayOfWeek]::Thursday)

Which gives the same result. Now users of your function don’t have to remember which number represents Thursday, they can simply use the name of our enum followed by the day of the week. All of this without the need to modify our IsItHamClubNight function!

Getting the Enum Values

Let’s say you know the enum you want to use is DaysOfWeek, but you can’t quite recall the various day names. Was it Monday, or the short abbreviation Mon? Or maybe you just want the full list so you can iterate over them.

The Enum type has a method, GetEnumNames. It can be used to retrieve the members of the enum.

[DaysOfWeek].GetEnumNames()

Result:

Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday

It actually returns a collection so you can use it to iterate over the members, as in a foreach loop.

foreach( $enumValue in [DaysOfWeek].GetEnumNames() )
{
  Write-Host "Enum Value is $enumValue"
}

Result:

Enum Value is Sunday
Enum Value is Monday
Enum Value is Tuesday
Enum Value is Wednesday
Enum Value is Thursday
Enum Value is Friday
Enum Value is Saturday

Alternatively you can pipe it, for example into a ForEach-Object.

[DaysOfWeek].GetEnumNames() |
  ForEach-Object { "{0} {1}" -f $_, [int]([DaysOfWeek]::$_) }

Result:

Sunday 0
Monday 1
Tuesday 2
Wednesday 3
Thursday 4
Friday 5
Saturday 6

This looks a bit cryptic so let me break it down. The "{0} {1}" -f indicates we want to create a formatted string. The {0} and {1} are placeholders. After the -f is a list of values. The first value will go into the {0}, the second into the {1}.

The next thing you see is $_. This is simply a PowerShell shortcut for "the current object coming through the pipeline". From the enum, Sunday will be first, then Monday, and so on.

Next you see [int]([DaysOfWeek]::$_). The [int] is used to convert what comes after it into an integer value. Next, we access the DayOfWeek enum, and give it the current object.

As a result, the output displays both the name from the enum, as well as the value associated with it.

If you want to learn more about string formatting, I’ll refer you to my post Fun With PowerShell String Formatting.

Enums with Duplicate Values

It is possible to assign the same numeric value to multiple items in an enum. For each position in our radio club, we want to indicate their level. President and Vice President are at the top, with Secretary and Treasurer in the second tier. Finally there are some appointed positions that are important, but not the top of the chain.

Here’s how this might be expressed in an enum.

Enum ClubPositions
{
  President = 1
  VicePresident = 1
  Secretary = 2
  Treasurer = 2
  Webmaster = 3
  Greeter = 3
  SnackBringer = 3
}

We can do comparisons between our various offices and their associated numeric value.

[ClubPositions]::President -eq 1
[ClubPositions]::VicePresident -eq 1

Result:

True
True

You can even compare two enums to each other.

[ClubPositions]::President -eq [ClubPositions]::VicePresident

Result:

True

Remember the GetEnumNames method we looked at a moment ago? This works as well.

[ClubPositions].GetEnumNames()

Result:

President
VicePresident
Secretary
Treasurer
Webmaster
Greeter
SnackBringer

There is one other method very similar to GetEnumNames, GetEnumValues. It doesn’t work quite like you’d think though.

First, let’s use it with our DaysOfWeek enum.

[DaysOfWeek].GetEnumValues()

Result:

Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday

As you can see, there’s no real difference compared to GetEnumNames. But now let’s run it for the ClubPositions enum.

[ClubPositions].GetEnumValues()

Result:

VicePresident
VicePresident
Treasurer
Treasurer
Greeter
Greeter
Greeter

In the second example it went through the enum, and only returned one text value for each integer. This is why we only see one entry for each numeric value.

It actually does the same thing with the DaysOfWeek enum, but because we only used each integer value once, only one label for each value was returned.

Conclusion

Using enums to aid with code clarity was the first item in this blog post. We then saw how to assign values to the individual members of an enum, as well as how to iterate over the members of an enum.

In the next article in this series, we’ll look at the concept of using enums as bit flags for when you need to save multiple states for a single item.

The demos in this series of blog posts were derived from my Pluralsight course PowerShell 7 Quick Start for Developers on Linux, macOS and Windows, one of many PowerShell courses I have on Pluralsight. All of my courses are linked on my About Me page.

If you don’t have a Pluralsight subscription, just go to my list of courses on Pluralsight . At the top is a Try For Free button you can use to get a free 10 day subscription to Pluralsight, with which you can watch my courses, or any other course on the site.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s