Welcome PowerShell User! This recipe is just one of the hundreds of useful resources contained in the PowerShell Cookbook.
If you own the book already, login here to get free, online, searchable access to the entire book's content.
If not, the Windows PowerShell Cookbook is available at Amazon, or any of your other favourite book retailers. If you want to see what the PowerShell Cookbook has to offer, enjoy this free 90 page e-book sample: "The Windows PowerShell Interactive Shell".
You want to work with the individual bits of a number or work with a number built by combining a series of flags.
To directly enter a hexadecimal number, use the 0x
prefix:
PS > $hexNumber = 0x1234 PS > $hexNumber 4660
To convert a number to its binary representation, supply a base of 2
to the
[Convert]::ToString()
method:
PS > [Convert]::ToString(1234, 2) 10011010010
To convert a binary number into its decimal representation, use the binary prefix 0b
:
$myBinary
=
0b10011010010
If you have the value as a string, supply a base of 2
to the [Convert]::ToInt32()
method:
PS > [Convert]::ToInt32("10011010010", 2) 1234
To manage the individual bits of a number, use PowerShell’s binary operators. In this case, the Archive
flag is just one of the many possible attributes that may be true of a given file:
PS > $archive = [System.IO.FileAttributes] "Archive" PS > attrib +a test.txt PS > Get-ChildItem | Where { $_.Attributes -band $archive } | Select Name Name ---- test.txt PS > attrib -a test.txt PS > Get-ChildItem | Where { $_.Attributes -band $archive } | Select Name PS >
In some system administration tasks, it’s common to come across numbers that seem to mean nothing by themselves. The attributes of a file are a perfect example:
PS > (Get-Item test.txt).Encrypt() PS > (Get-Item test.txt).IsReadOnly = $true PS > [int] (Get-Item test.txt -force).Attributes 16417 PS > (Get-Item test.txt -force).IsReadOnly = $false PS > (Get-Item test.txt).Decrypt() PS > [int] (Get-Item test.txt).Attributes 32
What can the numbers 16417
and 32
possibly tell us about the file?
The answer to this comes from looking at the attributes in another light—as a set of features that can be either true or false. Take, for example, the possible attributes for an item in a directory shown by Example 6-3.
PS > [Enum]::GetNames([System.IO.FileAttributes]) ReadOnly Hidden System Directory Archive Device Normal Temporary SparseFile ReparsePoint Compressed Offline NotContentIndexed Encrypted IntegrityStream NoScrubData
If a file is ReadOnly
, Archive
, and Encrypted
, then you might consider the following as a succinct description of the attributes on that file:
ReadOnly
=
True
Archive
=
True
Encrypted
=
True
It just so happens that computers have an extremely concise way of representing sets of true and false values—a representation known as binary. To represent the attributes of a directory item as binary, you simply put them in a table. We give the item a 1 if the attribute applies to the item and a 0 otherwise (see Table 6-1).
Attribute | True (1) or false (0) |
---|---|
|
1 |
|
0 |
|
0 |
|
0 |
|
0 |
|
0 |
|
0 |
|
0 |
|
0 |
|
1 |
|
0 |
<Unused> |
0 |
|
0 |
|
0 |
|
1 |
If we treat those features as the individual binary digits in a number, that gives us the number 100000000100001. If we convert that number to its decimal form, it becomes clear where the number 16417
came from:
PS > 0b100000000100001 16417
This technique sits at the core of many properties that you can express as a combination of features or flags. Rather than list the features in a table, though, the documentation usually describes the number that would result from that feature being the only one active—such as FILE_ATTRIBUTE_REPARSEPOINT = 0x400
. Example 6-4 shows the various representations of these file attributes.
PS > $attributes = [Enum]::GetValues([System.IO.FileAttributes]) PS > $attributes | Select-Object ` @{"Name"="Property"; "Expression"= { $_ } }, @{"Name"="Integer"; "Expression"= { [int] $_ } }, @{"Name"="Hexadecimal"; "Expression"= { [Convert]::ToString([int] $_, 16) } }, @{"Name"="Binary"; "Expression"= { [Convert]::ToString([int] $_, 2) } } | Format-Table -auto Property Integer Hexadecimal Binary -------- ------- ----------- ------ ReadOnly 1 1 1 Hidden 2 2 10 System 4 4 100 Directory 16 10 10000 Archive 32 20 100000 Device 64 40 1000000 Normal 128 80 10000000 Temporary 256 100 100000000 SparseFile 512 200 1000000000 ReparsePoint 1024 400 10000000000 Compressed 2048 800 100000000000 Offline 4096 1000 1000000000000 NotContentIndexed 8192 2000 10000000000000 Encrypted 16384 4000 100000000000000 IntegrityStream 32768 8000 1000000000000000 NoScrubData 131072 20000 100000000000000000
Knowing how that 16417
number was formed, you can now use the properties in meaningful ways. For example, PowerShell’s -band
operator allows you to check whether a certain bit has been set (assuming that you’ve set test.txt
to be encrypted through either the Explorer UI or other means):
PS > $encrypted = 16384 PS > $attributes = (Get-Item test.txt -force).Attributes PS > ($attributes -band $encrypted) -eq $encrypted True PS > $compressed = 2048 PS > ($attributes -band $compressed) -eq $compressed False
Although that example uses the numeric values explicitly, it would be more common to enter the number by its name:
PS > $archive = [System.IO.FileAttributes] "Archive" PS > ($attributes -band $archive) -eq $archive True
For more information about PowerShell’s binary operators, see “Simple Operators”.
“Simple Operators”