Nov 10, 2016

How to Use enums in PowerShell


Microsoft introduced enum (enumeration) in PowerShell 5 that allows you to predefine a set of allowed values for a variable. In this PowerShell guide, we'll walk you through the steps to outline usage scenarios for enums in PowerShell scripts.





Even though enums have multiple applications in various languages, I’ve found that they are most useful when writing code that prevents duplication.

Let me make you understand what is enums?

Enums, in fact, are simple constructs in any programming language. They are just a list of items in a collection. They are a way of setting a predefined set of items that are associated with a common type. I know that might be hard to grasp, so let’s look at an example.

Enums allow me to create a set of predefined items ahead of time. Once I have this set created, I can then implement it in different ways. For this guide, I’ll go over a great use case for enums.

Let’s say you have a script that you’ve created to give to your helpdesk. This script creates Active Directory users. You want to limit in which OUs this script can create users. To do this, you can define an enum of allowed OUs. To create an enum in PowerShell 5.0, I use the enum keyword followed by each item that’s a part of that enum.

enum AllowedOUs
{
    CompanyUsers
    Accounting
    HR
    IT
}

In above script, you can see we have an enum called AllowedOUs with four items inside. Once we do this, we can then reference all of the items in this enum by using two colons after specifying the AllowedOUs enumerated type. You can see below that the ISE knows what items are already in this enum, and Intellisense is kicking in to give me the list.

ISE knows the items in this enum and Intellisense provides the list

Note: There are a few gotchas with enums. First, the items in the enum cannot have spaces. So, don’t even try to surround them with quotes; it’s not going to work. In addition, enums cannot have special characters except an underscore. Just remember that the items are just simple strings.

Now that I have created the enum, how can I use it to restrict my helpdesk users from adding users into any OU they like? To demonstrate, let’s start with a simple function template to do this.

function New-CompanyXActiveDirectoryUser {
    param (
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$UserName,
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$FirstName,
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$LastName,
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$OrganizationalUnit
    )
    $params = @{
        Name = $UserName
        SamAccountName = $UserName
        GivenName = $FirstName
        SurName = $LastName
        Path = $OrganizationalUnit
    }
    New-Aduser -Name $UserName -SamAccountName $UserName -GivenName $FirstName -SurName $LastName –Server mydc –Enabled $true
}


You’ll see that I’m building a helper function around the New-AdUser cmdlet. This gives me the ability to not only restrict the input to the cmdlet but to also provide some default values. However, anyone using this function can pass anything they want to the OrganizationalUnit parameter. Let’s fix that by using the enum that we created earlier.

[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[AllowedOUs]$OrganizationalUnit

Notice the simple change? I just changed the type from string to AllowedOUs. You can see below that the ISE again knows that this is an enum and provides us with list of items, just like the ValidateSet parameter validation attribute does.

ISE knows that this is an enum and provides us with the list of items

If I try to pass something other than an item in the enum, I’ll immediately get an error and be presented with a list of allowable items.

An error and a list of allowable items

You might think, “Big whoop! I can do that with the ValidateSet parameter validation attribute.” True, but do you recall my intro where I mentioned not to repeat yourself? What if you had another function that removed an AD user and that same OU restriction needs to be placed there as well? At that point, you’d have two functions with this exact same parameter:

[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[ValidateSet('CompanyUsers','HR','Accounting','IT')]
[string]$OrganizationalUnit

Now you’ve got duplicate references, and if another OU needs to be added, it would have to be done in two different spots. But an enum can be used in multiple places. Simply set the parameter type to [AllowedOUs] in as many functions as you like, and they will all follow the same pattern.

function Function1 {
    param(
        [AllowedOUs]$OrganizationalUnit
    )
}
function Function2 {
    param(
        [AllowedOUs]$OrganizationalUnit
    )
}






 

Conclusion

Using enums is not only an excellent way to organize items but is also a great way to create a shared ValidateSet validation attribute as well.

Post a Comment

 
TECH SUPPORT © 2012 - Designed by INFOSBIRD