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.

3 comments:

  1. Greetings, Andy- Thanks for the info in this post -- quite helpful.

    Minor suggestion for performance improvement: have the Add-Type portion be outside of the function definition (instead of the "Add-Type" piece being called for every file being unblocked). Probably slight, but it adds up.

    Thanks again

    Matt (vNugglets.com)

    ReplyDelete
  2. Hi Matt, actually the object created by Add-Type only gets created once since it is in the begin block. PowerShell will call the begin block on all cmdlets and script cmdlets before anything is passed through the pipeline. So in this function the object is only created once and used for every item passed in from the pipeline.

    ReplyDelete
  3. Casino Tycoon - Mapyro
    Find Casino Tycoon, Best 하남 출장샵 Casino 청주 출장샵 Tycoon in Las Vegas, 동두천 출장안마 NV, United States and see activity. 3, 원주 출장마사지 4, 5, 6, 7, 8, 9. Casino Tycoon. Mapyro - Mapyro 논산 출장안마

    ReplyDelete