Today we will take a look at the Bitwise Operators in Windows PowerShell and how you can manipulate them for your needs.  First we will get some insight into the enumeration. Let’s begin by looking at the values for the [System.IO.FileAttributes] enumeration which provides attributes for files and directories.

As you can see from the table below each member corresponds to a different attribute that you can apply to files and directories. Some of these are common values that you see daily such as ReadOnly and Hidden, but others are not so common. I won’t go into the meaning of each of these, but if you are interested you can review them on the MSDN site here. Each value, in decimal, is a power of 2 greater than the previous value. To add attributes you add the binary value. So the attributes for a file that is ReadOnly and Hidden would be "1" + "10" = "11" or 3.

An interesting note is that given any enumeration value there can be only ONE possible combination of values that will add up to the enumeration value.

Member Name Binary Value Decimal Value
ReadOnly 1 1
Hidden 10 2
System 100 4
Directory 10000 16
Archive 100000 32
Device 1000000 64
Normal 10000000 128
Temporary 100000000 256
SparseFile 1000000000 512
Compressed 10000000000 2048
Offline 100000000000 4096
Encrypted 1000000000000 16384

So. Enough for the theory. Let’s have fun.

Determining if an attribute is set

The first task we want to accomplish is checking to see whether an attribute is set on a specified file. In this case we are using a file called "test.txt" with the Hidden and ReadOnly attributes set. First we get the file information and attributes. Then we use the -band bitwise operator to compare the objects.

$File = Get-ChildItem .\test.txt -Force
$File.Attributes
if ( $File.Attributes -band [System.IO.FileAttributes]::Hidden )
{ Write-Host "Hidden Attribute Set" }

With the "-band" operator each binary value is compared and in each position if a 1 is present in both numbers then a 1 is returned. If not, a 0 is returned. So for our example "11 -band 10" is equal to 10 because a 1 is in the second position in both numbers. The way that enumerations are setup dictate two possible values for this comparison. Either the returned value is equal to the attribute being compared or 0, indicating that the attribute is not set.

Setting an attribute

The next task we want to perform is setting an attribute. We are going to use the same file we used in the previous example and set the System attribute. For this task we are going to use the -bor operator.

$File = Get-ChildItem .\test.txt -Force
$File.Attributes
$File.Attributes = ( $File.Attributes -bor [System.IO.FileAttributes]::System )
$File.Attributes

Here, by using the "-bor" operator each binary value is compared and in each position if there is a one present in either number then a one is returned for that position. It’s like a light switch. If it is turned on in either number then it is turned on in the resulting output.  Using this analogy we are flipping on the switch that corresponds to the System attribute.

Removing an attribute

The last task is removing an attribute. For this example we are using the "-bxor" operator. This operator is like a two-way light switch. If you turn on one light switch, the light is on. If you then turn on the other switch, the light turns off.  So you can probably see the issue. If you run the following script a couple of times on the same file you will notice that the System attributes gets turned on or off each time you run it.

$File = Get-ChildItem .\test.txt -Force
$File.Attributes
$File.Attributes = ( $File.Attributes -bxor [System.IO.FileAttributes]::System )
$File.Attributes

This is good if you want to set an attribute to the opposite of the current setting. However if you want to just remove an attribute you will need the following script.


$File = Get-ChildItem .\test.txt -Force
$File.Attributes
if (  $File.Attributes -band [System.IO.FileAttributes]::System)
{ $File.Attributes = ( $File.Attributes -bxor [System.IO.FileAttributes]::System )  } $File.Attributes

We use the "-band" operator to make sure the option is set and then unset it using the "-bxor" operator.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • email
  • Identi.ca
  • LinkedIn
  • Live
  • MySpace
  • Netvibes
  • NewsVine
  • Ping.fm
  • Technorati
  • TwitThis
  • FriendFeed
  • Print
  • RSS