Bitwise operators perform operations on the individual bits of integer values. PowerShell provides six bitwise operators: -band (AND), -bor (OR), -bxor (XOR), -bnot (NOT), -shl (shift left), and -shr (shift right). These operators are essential for low-level tasks such as working with bit flags, permissions, binary protocols, and performance-sensitive code.
Operators at a Glance
| Operator | Name | Description | Example |
|---|---|---|---|
-band |
Bitwise AND | Sets a bit to 1 only if both operands have 1 in that position |
6 -band 3 → 2 |
-bor |
Bitwise OR | Sets a bit to 1 if either operand has 1 in that position |
6 -bor 3 → 7 |
-bxor |
Bitwise XOR | Sets a bit to 1 if exactly one operand has 1 in that position |
6 -bxor 3 → 5 |
-bnot |
Bitwise NOT | Flips all bits (unary operator) | -bnot 6 → -7 |
-shl |
Shift left | Shifts bits left by n positions (multiplies by 2ⁿ) | 3 -shl 2 → 12 |
-shr |
Shift right | Shifts bits right by n positions (divides by 2ⁿ) | 12 -shr 2 → 3 |
Understanding Bitwise Operations
To understand bitwise operators, it helps to see the binary representation of numbers. For simplicity, we'll use 8-bit binary representations (PowerShell actually uses 32-bit or 64-bit integers depending on the type, but the principle is the same).
Binary Representation Examples
| Decimal | Binary (8-bit) |
|---|---|
| 0 | 00000000 |
| 1 | 00000001 |
| 2 | 00000010 |
| 3 | 00000011 |
| 4 | 00000100 |
| 5 | 00000101 |
| 6 | 00000110 |
| 7 | 00000111 |
Bitwise AND (-band)
The -band operator compares each bit of two integers. If both bits are 1, the result bit is 1; otherwise, it is 0.
Truth Table for AND
| Bit A | Bit B | A -band B |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
Example
6 -band 32Binary breakdown:
6: 00000110
3: 00000011
------------- -band
2: 00000010Bitwise OR (-bor)
The -bor operator compares each bit of two integers. If either bit is 1, the result bit is 1; otherwise, it is 0.
Truth Table for OR
| Bit A | Bit B | A -bor B |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 1 |
Example
6 -bor 37Binary breakdown:
6: 00000110
3: 00000011
------------- -bor
7: 00000111Bitwise XOR (-bxor)
The -bxor operator compares each bit of two integers. If exactly one bit is 1, the result bit is 1; otherwise, it is 0.
Truth Table for XOR
| Bit A | Bit B | A -bxor B |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
Example
6 -bxor 35Binary breakdown:
6: 00000110
3: 00000011
------------- -bxor
5: 00000101Bitwise NOT (-bnot)
The -bnot operator is unary and flips all bits of its operand: 0 becomes 1, and 1 becomes 0. In two's complement representation (used by PowerShell), this is equivalent to -(n + 1).
Truth Table for NOT
| Bit A | -bnot A |
|---|---|
| 0 | 1 |
| 1 | 0 |
Example
-bnot 6-7Binary breakdown (8-bit for illustration):
6: 00000110
-------------- -bnot
-7: 11111001 (two's complement representation of -7)Bit Shift Operators
Bit shift operators move bits left or right by a specified number of positions. They are equivalent to multiplying or dividing by powers of two.
Shift Left (-shl)
-shl shifts bits to the left. Vacated bits on the right are filled with 0. The value is multiplied by 2ⁿ, where n is the shift count.
3 -shl 212Binary breakdown:
3: 00000011
------------- -shl 2
12: 00001100Shift Right (-shr)
-shr shifts bits to the right. For signed integers, the vacated bits on the left are filled with the sign bit (arithmetic shift). For unsigned integers, they are filled with 0 (logical shift). The value is divided by 2ⁿ, discarding any remainder.
12 -shr 23Binary breakdown:
12: 00001100
------------- -shr 2
3: 00000011Shift Count Behavior
- If the shift count is greater than or equal to the bit width of the type, the result is
0for left shifts and0or-1(for signed negative numbers) for right shifts. - Negative shift counts are not allowed and will cause an error.
Operator Precedence
Bitwise operators have lower precedence than arithmetic operators but higher precedence than comparison and logical operators. The order is:
- Unary operators:
-bnot,-not,! - Arithmetic:
*,/,% - Arithmetic:
+,- - Shift:
-shl,-shr - Bitwise AND:
-band - Bitwise XOR:
-bxor - Bitwise OR:
-bor - Comparison:
-eq,-ne, etc. - Logical:
-and,-or,-xor - Assignment:
=,+=, etc.
Parentheses always override precedence.
$result1 = 6 -band 3 -bor 1
$result2 = 6 -band (3 -bor 1)
[PSCustomObject]@{
WithoutParentheses = $result1
WithParentheses = $result2
}WithoutParentheses WithParentheses
------------------ ---------------
3 2Practical Examples
1. Working with Bit Flags (Permissions)
Bit flags are commonly used to represent multiple boolean options in a single integer. Each bit represents a different permission.
$Read = 1 # 0001
$Write = 2 # 0010
$Execute = 4 # 0100
$Delete = 8 # 1000
$userPermissions = $Read -bor $Write # 0011 = 3
$canRead = ($userPermissions -band $Read) -ne 0
$canExecute = ($userPermissions -band $Execute) -ne 0
$userPermissions = $userPermissions -bor $Execute # 0111 = 7
$userPermissions = $userPermissions -band (-bnot $Write) # 0101 = 5
[PSCustomObject]@{
Permissions = $userPermissions
CanRead = $canRead
CanExecute = $canExecute
CanWrite = ($userPermissions -band $Write) -ne 0
CanDelete = ($userPermissions -band $Delete) -ne 0
}Permissions : 5
CanRead : True
CanExecute : False
CanWrite : False
CanDelete : False2. Toggling Bits with XOR
$value = 0b1010 # 10 in decimal
$mask = 0b1111
$toggled = $value -bxor $mask
$restored = $toggled -bxor $mask
[PSCustomObject]@{
Original = $value
Toggled = $toggled
Restored = $restored
}Original Toggled Restored
-------- ------- --------
10 5 103. Fast Multiplication and Division with Shifts
$value = 7
$timesTwo = $value -shl 1 # 7 * 2 = 14
$timesFour = $value -shl 2 # 7 * 4 = 28
$divByTwo = $value -shr 1 # 7 / 2 = 3 (integer division)
$divByFour = $value -shr 2 # 7 / 4 = 1
[PSCustomObject]@{
Original = $value
TimesTwo = $timesTwo
TimesFour = $timesFour
DivByTwo = $divByTwo
DivByFour = $divByFour
}Original : 7
TimesTwo : 14
TimesFour : 28
DivByTwo : 3
DivByFour : 14. Extracting Color Components (RGB)
$argb = 0xFF336699
$alpha = ($argb -shr 24) -band 0xFF
$red = ($argb -shr 16) -band 0xFF
$green = ($argb -shr 8) -band 0xFF
$blue = $argb -band 0xFF
[PSCustomObject]@{
Alpha = $alpha
Red = $red
Green = $green
Blue = $blue
}Alpha Red Green Blue
----- --- ----- ----
255 51 102 153Best Practices
- Use bitwise operators only on integers. Avoid using them on booleans or strings; use logical operators for boolean logic.
- Always use parentheses to group bitwise expressions and avoid precedence surprises.
- Define named constants for bit flags rather than using magic numbers.
- Be mindful of signedness.
-bnoton a signed integer produces a negative number; use unsigned types or masks to control the result. - Use shifts for powers of two when clarity is not sacrificed, but prefer multiplication/division for readability in high-level code.
- Test bitwise logic thoroughly. Binary representations can be tricky; use
[Convert]::ToString($value, 2)to inspect binary values during debugging.