In PowerShell 5, the new support for enums makes dealing with bit values much easier as you’ve seen in previous tips. Even setting or clearing bits no longer requires cumbersome logical operators anymore.
Let’s first define an enum and make the decimal more manageable:
#requires -Version 5 [Flags()] enum GardenPartyItems { Chair = 0 Table = 1 Barbecue = 2 Fridge = 4 Candle = 8 Knife = 16 } $decimal = 11 [GardenPartyItems]$flags = $decimal $flags
Now, the bits from any decimal can be easily converted to a list of garden party items:
PS C:\> [GardenPartyItems]11 Table, Barbecue, Candle PS C:\>
Important: when you cast a decimal to an enumeration, always make sure that all bits are defined in your enum. If the decimal is too large and contains more bits than your enum, the conversion fails.
To add a new flag, try this:
PS C:\> $flags Table, Barbecue, Candle PS C:\> $flags += [GardenPartyItems]::Knife PS C:\> $flags Table, Barbecue, Candle, Knife PS C:\>
To remove a flag, do this:
PS C:\> $flags Table, Barbecue, Candle, Knife PS C:\> $flags -= [GardenPartyItems]::Candle PS C:\> $flags Table, Barbecue, Knife PS C:\>
However, this is not as straightforward as it seems. When you remove a flag that was set before, you are fine. But when you remove a flag that wasn’t there in the first place, you mess up your bit values:
PS C:\> $flags Table, Barbecue, Candle PS C:\> $flags -= [GardenPartyItems]::Candle PS C:\> $flags Table, Barbecue PS C:\> $flags -= [GardenPartyItems]::Candle PS C:\> $flags -5 PS C:\>
So obviously PowerShell isn’t clever enough (yet) to use binary arithmetic automatically. To play safe, you’d still have to use binary operators. To remove flags, use -band and -bnot:
PS C:\> $flags Table, Barbecue, Candle PS C:\> $flags = $flags -band -bnot [GardenPartyItems]::Candle PS C:\> $flags Table, Barbecue PS C:\> $flags = $flags -band -bnot [GardenPartyItems]::Candle PS C:\> $flags Table, Barbecue PS C:\>
And to set flags, use -bor:
PS C:\> $flags Table, Barbecue, Candle PS C:\> $flags = $flags -bor [GardenPartyItems]::Knife PS C:\> $flags Table, Barbecue, Candle, Knife PS C:\> $flags = $flags -bor [GardenPartyItems]::Knife PS C:\> $flags Table, Barbecue, Candle, Knife PS C:\>
In all of these operations, you were working with just a decimal:
PS C:\> [Int]$flags 19
Awesome, eh?