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])](https://cdn.prod.website-files.com/6821b5175dd850cde4c319dc/682f18aa42ede08635c4a683_image-png-Aug-20-2024-03-06-23-9405-PM.png)
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]) }](https://cdn.prod.website-files.com/6821b5175dd850cde4c319dc/682f18aa42ede08635c4a698_image-png-Aug-20-2024-03-07-15-4741-PM.png)
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__](https://cdn.prod.website-files.com/6821b5175dd850cde4c319dc/682f18aa42ede08635c4a68f_image-png-Aug-20-2024-03-08-27-8786-PM.png)
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])}](https://cdn.prod.website-files.com/6821b5175dd850cde4c319dc/682f18aa42ede08635c4a692_image-png-Aug-20-2024-03-12-02-9919-PM.png)
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]](https://cdn.prod.website-files.com/6821b5175dd850cde4c319dc/682f18aa42ede08635c4a695_image-png-Aug-20-2024-03-13-10-1569-PM.png)
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](https://cdn.prod.website-files.com/6821b5175dd850cde4c319dc/682f18aa42ede08635c4a68c_image-png-Aug-20-2024-03-13-49-7043-PM.png)
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

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.