Monday, February 20, 2012

Unblocking Files with PowerShell

When you download a file from the internet you may of seen this:

2012-02-19 01h38_17

If the file is an executable and you try to run it, you will be prompted if you want to run the file… Yea, yea… I just freaking downloaded it, I want to run it already! If you download a ZIP file (such as the Sysinternals Suite) you'll have to unblock every program in it…

So what's really going on is that something called an alternate data stream get's created for the file when you save it to disk. This is a special feature of NTFS that allows a file name to reference more than one data stream on disk. The primary data stream is just the data that the filename is referencing. So Test.zip points to a data stream and that's where the ZIP file data is stored. Alternate data streams are stored and accessed with the name of the file plus ':Data_Stream_Name' (a colon and the name of the alternate stream). These additional streams are hidden from Windows Explorer and the command prompt directory listing. Only special methods allow you to access them. When a file is downloaded from the internet an alternate access stream is created with the name 'Zone.Identifier'. The contents look like this:

ZoneId 3 means it came from the internet. This is what Windows uses to determine whether or not it should block the file. You can edit the file by opening it with Notepad from a command prompt like this:

However you cannot delete the alternate access stream from disk using this approach, only delete or change it's contents. There is a function called DeleteFile in Win32 API that will allow you to delete an alternate access stream however we can't call this from PowerShell directly. We will need to p/invoke using the Add-Type cmdlet.

I've wrapped this into a portable function that allows pipeline input. So you can pipe an entire set of files to this like so:

As I write this, PowerShell 3 is current in CTP2 and it does include a cmdlet for this. However if you are using PowerShell v2 this is the way to go.