Work with Numbers As Binary
1. Problem
You want to work with the individual bits of a number, or work with a number built by combining a series of flags.
2. Solution
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, 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 >
3. Discussion
In some system administration tasks, it is 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.
Example 6-3. Possible attributes of a file
PS >[Enum]::GetNames([System.IO.FileAttributes]) ReadOnly Hidden System Directory Archive Device Normal Temporary SparseFile ReparsePoint Compressed Offline NotContentIndexed Encrypted
|
If a file is ReadOnly, Archive, and Encrypted, then you might consider this 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).
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 >[Convert]::ToInt32("100000000100001", 2)
       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, documentation usually describes the number that would result from that feature being the only one active—such as FILE_ATTRIBUTE_REPARSEPOINT = 0×400. Example 6-4 shows the various representations of these file attributes.
Example 6-4. Integer, hexadecimal, and binary representations of possible file attributes
|
Code View: Scroll / Show All 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                                      Â
|
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 if a certain bit has been set:
       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
       PS >
Although the example above 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
Tags: archive, attributes, band, binary, cmd, directory, get-help, numers, ps, system, work 
