Ready to level up your PowerShell enum game? Discover how [Flags()] transforms simple enums into powerful binary combinations, allowing you to manage multiple settings with elegant precision perfect for feature flags, permission systems, and configuration management.

Tips by Tobias & Aleksandar:

Using enums

Simple enums define a list of allowed values, and the user can pick exactly one. When enums are defined as a flag array, then the user can pick more than one value:

[Flags()]enum Features{ BootLog RealTimeProtection Firewall PhysicalAccess Leash}[Features]$myFeatures = 'Firewall', 'Leash'$myFeatures

By adding the [Flags()] attribute to the enum, each enum entry now gets its own unique bit value, thus the user can combine as many enum items as needed. The type [Enum] can shed some light into this. Here it lists the defined enum names:

  • PS C:\> [Enum]::GetNames([Features])
PS C:\> [Enum]::GetNames([Features])

Next, it shows the assigned true numeric values:

  • PS C:\> [Enum]::GetNames([Features]) | ForEach-Object { '{0} = {1}' -f $_, ([Features]::$_ -as [int])}
PS C:\> [Enum]::GetNames([Features]) | ForEach-Object { '{0} = {1}' -f $_, ([Features]::$_ -as [int]) }

When you assign multiple values, bit values are added:

  • PS C:\> [Features]$myFeatures = 'Firewall', 'Leash'PS C:\> $myFeaturesFirewall, Leash PS C:\> $myFeatures.value__
PS C:\> [Features]$myFeatures = 'Firewall', 'Leash' PS C:\> $myFeatures Firewall, Leash PS C:\> $myFeatures.value__

There is just one problem: the assigned numbers are consecutive and thus ambiguous PhysicalAccess has ID 3, but RealTimeProtection+Firewall also adds to 3.

When you use [Flags()], you also need to manually assign unique values to the enum items:

[Flags()]enum Features{ BootLog = 1 RealTimeProtection = 2 Firewall = 4 PhysicalAccess = 8 Leash = 16}

Now each item has a unique ID:

  • PS C:\> [Enum]::GetNames([Features]) | ForEach-Object {'{0} = {1}' -f $_, ([Features]::$_ -as [int])}
PS C:\> [Enum]::GetNames([Features]) | ForEach-Object {'{0} = {1}' -f $_, ([Features]::$_ -as [int])}

Now, with unique IDs, you can use enums like any other numbers to do binary arithmetic:

  • PS C:\> [Features]'Bootlog,Leash'BootLog, LeashPS C:\> [Features]'Bootlog,Leash' -as [int]
PS C:\> [Features]'Bootlog,Leash' BootLog, Leash PS C:\> [Features]'Bootlog,Leash' -as [int]

Use the "+=" operator to add an element, and "-=" to remove it:

  • PS C:\> [Features]$features = 'Bootlog'PS C:\> $features += 'Leash'PS C:\> $features += 'Firewall'PS C:\> $featuresBootLog, Firewall, LeashPS C:\> $features -= 'Leash'PS C:\> $featuresBootLog, Firewall
PS C:\> [Features]$features = 'Bootlog' PS C:\> $features += 'Leash' PS C:\> $features += 'Firewall' PS C:\> $features BootLog, Firewall, Leash PS C:\> $features -= 'Leash' PS C:\> $features BootLog, Firewall

Likewise, when testing whether a given value is present in such a list, use binary operators like -band and -bor:

  • PS C:\> $featuresBootLog, FirewallPS C:\> ($features -band 'Firewall') -eq 'Firewall'TruePS C:\> ($features -band 'Leash') -eq 'Leash'False
PS C:\> $features BootLog, Firewall PS C:\> ($features -band 'Firewall') -eq 'Firewall' True PS C:\> ($features -band 'Leash') -eq 'Leash' False

Scriptember was great, thank you!

Did you enjoy Scriptember? We did! Thanks for being part of it and #KeepOnScripting

  • Follow us on social media, look for and use the hashtags #Scriptember and #PowerShell.

Related links