powershell enum

In part two of this web series about powershell classes, I would like to talk about how to use a powershell enum and go through a use case which will point out their use, and why you really want to integrate them into your scripts.

If you have missed the beginning of this blog post series, or if you are new to powershell classes, See part one here, and learn how powershell constructors and their overloads works in powershell 5 classes.

how to write a powershell enum to use in a powershell class

Since version 5 of powershell, we have the possibility to create powershell enumerations. Or more commonly called powershell enum.

What is a powershell enum? why would we even want to use a powershell enum? How do we create a powershell enum?

I’ll try to answer all of these questions in this blog post.

If you would like to see something to be covered more in depth, please let me know in the comment section below or tweet me at @stephanevg

To create a new powershell enumartion, we will use the new keyword “Enum“.

The very basics for a powershell Enum to exist would be to having something as represented as followed:

A powershell enum is used to offer a limited list of elements of a specefic type to your object.

For example, you could have a Enum called “ServerType” that would contain a list of all of your different type of servers. These are the ones that I have my lab, and which we will build the example.

When you would like to have a reference to one of you elements from your list you will query it as followed:

This would return the value “ConfigMgr

See by your self in the example below:

powershell Enums

powershell Enum

The value that is returned, is of type [ServerType], which we can use to include generic validation logic to our powershell code and by keeping it easily extensible.

I can imagine this to be used like some sort of ‘externalized parameter set‘ which can easily be modified, without impacting to drastically your code when we add a new server type to manage. The same powershell enum can then be used in several different places in our code while limiting copy pasting.

Now imagine this: Let’s say you have an IF ($variable) {}  condition in your code, and want to make sure that the value of $variable is part of a pre-defined list. You could sure use a text file to store the information in, xml, JSON or even a validateSet in your advance functions. If the if statement is equal to one of the values of your list, or let’s say, a specific value of the list, you want to execute some appropriate code. To do so, you would have to either use of bunch of if’s  and elseif’s ,  a Switch,  or/and a foreach construct.

Confusing right? Hang on, and look at the example below.

Let’s say, you have a new server type, like, for example a SCOM server, that would mean that you would have to adapt your if’s or your switch statements. Now if we do or methods like above, we can restrict it on the type and avoid us to adapt our main code. Using powershell enums will give quite some easy extensibility to our code.

Instead of having something like this:

We could do something as simple as this:

The advantage of the second method, is that to extend the functionality of our script to accept a new type of server, the only thing we need to do is to add new entry to the Enum Class.

Using the ‘-is‘ operator combined with a Enum Type, allows to check if several conditions are true, using a way more compact syntax.We are checking the type, instead of the real content, and leaving the door open to add new servertypes without impacting our inner logic.

Powershell enum contains constants:

We can also use a powershell enum to assign a value to each of the properties that composes the powershell enum, but there is an important thing to keep in mind: A powershell Enum can only be a constant.

A powershell enum can only contain constants. This means it cannot be a word, or the result of some query.

The code below assigns a constant to each value.

We can later on cast a value to the type of our powershell enum (in my example [ServerEnvironment]) and we will have the corresponding environment back.

powershell classes enum Casting

Constant can be assigned in any order, but it is not an obligation. By default, if you omit to put constants on your enums, they will still be accessible as in the example above. The only thing to keep in mind is that a powershell enum is 0 based.

One last thing to add to this, is the fact that you can add constants to your powershell enum, that does not necessarily starts at 0. In other words, you will be able to use your powershell enum as followed as well:

As a last point, and as explained above, it is possible to use integers to point to specific values of our Enum’s (Or better said, to their values).

Now, it is also possible to retriew their assigned values, based on their value. As usual, an example will make this clearer:

Sometimes, having access to the assigned value of your Enum might be more important than the Enum it self. Well, this got you covered.

This was actually implicitly suggested on reddit. Read the full comment on reddit here

Using a powershell enum in a concrete example

Ok, now that we have the theory covered around how to create a PowerShell enum, let’s make this concrete with an example. For that, I will reuse the class I wrote in part 1 of this blog series, and we will continue on this based through this complete series.

As a reminder, the code we ended up having at part 1 is the following one:

We will simply integrate our ServerType powershell enum into our already  existing code (see above), and make our existing classes more robust, and better prepared for the future.

As a reminder, this is our ServerType enum:

If we create an instance of our powershell class without the powershell enum, this is what the current result will be:

prior powershell enums

We do have an object, where the type is set to this string ‘plop‘ and the computer object has been created, but it set it in the “computerscontainer of our Active Directory. Also, you might have noticed that the computer account was named “woop“, which is definitely not an intelligent name for a computer (It might be for dog though!)

Please leave a comment if your dog’s name is “Woop”!

Using a powershell enum, we can make this more dynamic, and error prone. We will adapt the existing constructor to take a parameter $type of type [Servertype] and according to the type that is specified, we will put the computer in a specific organisational unit, and give it a correct prefix.

Seeting the computer account in the right OU using powershell classes and enums

Now that we have created our first computer object using powershell classes, we can go a step further and integrate the powershell enums to our logic.

We want to add logic in our existing class. The objective is to create the computer object in a specefic OU, according to the type of server we are willing to have. For that purpose, Enums are just perfect!

I have adapted slightly our main computer class, actually only the ‘constructor’ (To learn everything about constructors, read part 1 of my powershell class series). The parameter $Type , which was of type [string] before, will be of type [ServerType] from now on. This actually means that the value of $Type can only be one of the values that is specified in our enum block, which currently are:

  • HyperV
  • Sharepoint
  • Exchange
  • Web
  • ConfigMgr

I have added 3 things to our second constructor:

  1. I changed the ‘type’ of the variable $type from [string] to [ServerType]
  2. I have added a Switch that will according to the value of $type, set the variable $ou to a specefic path.
  3. Added the parameter -path with the value of $ou to the New-ADcomputer cmdlet.

The update version of our second constructor looks now like this:

(Find the complete class and Enum at the bottom of the post):

When creating an instance of our new version of our powershell class using the enum, we will have the following results:

powershell class and Enum ou

As highlighted in the image above, with the little logic we added in our constructor, we managed to set our new ConfigMgr server in the correct OU using a simple PowerShell Enum.

The full code (Class + Enum) is available here:

Read more about it!