# Command line utility to unblock files

## Recommended Posts

Wrote a command line utility which will unblock folders and files passed to it as a parameter.  You can pass as many files/folders as you want as a parameter.  If function detects "-r" or "/r" as first parameter, will unblock files recursively for directories that are passed to it.  Will perform following actions:

1) determine version of powershell installed on computer

2) if powershell version is greater than or equal to 3, will use powershell to unblock the files.  Otherwise, will download "streams.exe" for 32-bit systems and "streams64.exe" for 64-bits systems from sysinternals live server and unblock files by deleting the alternate streams on indicated folders.

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=y
#AutoIt3Wrapper_Change2CUI=y
#AutoIt3Wrapper_Res_SaveSource=y
#AutoIt3Wrapper_Res_Language=1033
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
; *** Start added by AutoIt3Wrapper ***
#include <InetConstants.au3>
; *** End added by AutoIt3Wrapper ***
; *** Start added by AutoIt3Wrapper ***
#include <AutoItConstants.au3>
#include <WinAPIShPath.au3>
; *** End added by AutoIt3Wrapper ***
#cs ----------------------------------------------------------------------------

AutoIt Version: 3.3.15.0 (Beta)
Author:         myName

Script Function:
Template AutoIt script.

#ce ----------------------------------------------------------------------------

#include <Array.au3>
#include <File.au3>
#include <WinAPIFiles.au3>
Opt("ExpandEnvStrings", 1)
$aCmdLine = _WinAPI_CommandLineToArgv($CmdLineRaw)
$recurs = False If$aCmdLine[1] = "/?" And Int($aCmdLine[0]) = 1 Then ConsoleWrite(@CRLF & @CRLF & @TAB & @TAB & @TAB & @TAB & @TAB & "Unblock Files Command Line Utility" & @CRLF & @CRLF & "Unblock files." & @CRLF & "new_unblock.exe [/r] [[[drive:][path][filename]0] .... [[drive:][path][filename]n]]" & _ @CRLF & @CRLF & "/r" & @TAB & "if any of the paths that are passed to the tool are directories, this switch will recursively unblock all files within the directory." & _ @CRLF & @CRLF & "[[[drive:][path][filename]0] .... [[drive:][path][filename]n]]" & @TAB & "The paths that are passed to the tool to be unblocked. These paths can be files or folders. If a folder is specified, only the files in the root of that directory will be unblocked unless the /r switch is specified." & @CRLF) ElseIf$aCmdLine[1] = "/?" And Int($aCmdLine[0]) > 1 Then ConsoleWriteError('Unexpected number of arguments. For information on how to use this tool, run "new_unblock.exe /?".' & @CRLF) Else For$i = 1 To $aCmdLine[0] Step 1 If ($aCmdLine[$i] = "/r" Or$aCmdLine[$i] = "-r") And$i = 1 Then
$recurs = True ContinueLoop EndIf If IsFile($aCmdLine[$i]) = 0 Then If$recurs = True Then
$files = _FileListToArrayRec($aCmdLine[$i], "*",$FLTAR_FILES, $FLTAR_RECUR) Else$files = _FileListToArray($aCmdLine[$i], "*", $FLTA_FILES) EndIf For$b = 1 To $files[0] Step 1 If FileExists($aCmdLine[$i] & "\" &$files[$b] & ":Zone.Identifier") Then ConsoleWrite ( "Unblocking file " &$aCmdLine[$i] & "\" &$files[$b] & @CRLF ) _WinAPI_DeleteFile($aCmdLine[$i] & "\" &$files[$b] & ":Zone.Identifier:$DATA")
Else
ContinueLoop
EndIf
Next
Else
If FileExists($aCmdLine[$i] & ":Zone.Identifier") Then
ConsoleWrite ( "Unblocking file " & $aCmdLine[$i] & @CRLF )
_WinAPI_DeleteFile($aCmdLine[$i] & ":Zone.Identifier:$DATA") Else ContinueLoop EndIf EndIf Next ConsoleWrite ( "DONE" & @CRLF ) EndIf Func IsFile($sFilePath)
Return Number(FileExists($sFilePath) And StringInStr(FileGetAttrib($sFilePath), "D", 2, 1) = 0)
EndFunc   ;==>IsFile

*Edit 2/3/2017: I updated the code so that, when the powershell method is used, a path that is under "Program files" or "program files (x86)" does not return an error.

**EDIT: The script has been re-written so that it is able to accomplish the same functionality without any prerequisites.  Only runs pure AutoIT now.  A big thanks to @argumentum for the idea.

Edited by MattHiggs
• 1

##### Share on other sites

**Updated.  Now allows users to successfully pass environment variables as part of the path specified in the arguments.  Also made some changes to improve performance.

##### Share on other sites

What exactly do you mean by unblock?

Does this take ownership of files and allow you to delete them when owned by another user or does this literally remove locks on files when held by another process, such as when scite has a lock on the parent folder of the open script and does nto allow you to delete it until the process is closed

##### Share on other sites
7 hours ago, Chance said:

What exactly do you mean by unblock?

Does this take ownership of files and allow you to delete them when owned by another user or does this literally remove locks on files when held by another process, such as when scite has a lock on the parent folder of the open script and does nto allow you to delete it until the process is closed

Hello Sir.  No.  This script will allow you to eliminate occurrences like these:

When this property is set on a file (usually when a file is downloaded from the internet), you will encounter the following when trying to run it:

For example, say you download a powershell  script from Microsoft's  script repository (let say this one for example.)  When you download it, you can verify by right clicking the file, selecting properties, and looking at the security attribute that the file is blocked.  If you try to utilize this script (the example has to be "dot sourced" first, which basically means you type in ". Path\to\script\script.ps1" into powershell console) without first unblocking the file, the below prompt will appear every time:

Which, if you are trying to automate a process, will kind of get in the way of that.  The script I have provided will remove the blocked status from the files which are passed to it in the command line, thus removing the extra prompt that appears before executing.

Edited by MattHiggs

##### Share on other sites

There's a PS cmdlet that does the same thing without having to download anything, use Unblock-File -Path <filepath\filename>

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

##### Share on other sites
1 hour ago, BrewManNH said:

There's a PS cmdlet that does the same thing without having to download anything, use Unblock-File -Path <filepath\filename>

You should take a look at the description/script source....

Edited by MattHiggs

##### Share on other sites

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

##### Share on other sites
8 hours ago, BrewManNH said:

No worries dude...  I would be lying if I said I wasn't guilty of the same, lol.

##### Share on other sites

oh snap, I see now. This is useful when you download a project and keep getting that dumb untrusted warning.

Thanks

##### Share on other sites
10 hours ago, Chance said:

oh snap, I see now. This is useful when you download a project and keep getting that dumb untrusted warning.

Thanks

Exactly..

##### Share on other sites

why not just:

If FileExists($sFile & ":Zone.Identifier") Then FileClose(FileOpen($sFile & ":Zone.Identifier", 2))
FileWrite($sFile & ":Zone.Identifier", "[ZoneTransfer]" & @CRLF & "ZoneId=0" & @CRLF) ; ZoneId=5 would work too EndIf not as clean but it'd solve the problem without the prerequisites. Thanks for sharing @MattHiggs Edit: Found a way to delete the stream #include <WinAPIFiles.au3> If FileExists($sFile & ":Zone.Identifier") Then
_WinAPI_DeleteFile($sFile & ":Zone.Identifier:$DATA") ; this will remove the stream
EndIf

Edited by argumentum

##### Share on other sites
17 hours ago, argumentum said:

why not just:

If FileExists($sFile & ":Zone.Identifier") Then FileClose(FileOpen($sFile & ":Zone.Identifier", 2))
FileWrite($sFile & ":Zone.Identifier", "[ZoneTransfer]" & @CRLF & "ZoneId=0" & @CRLF) ; ZoneId=5 would work too EndIf not as clean but it'd solve the problem without the prerequisites. Thanks for sharing @MattHiggs Edit: Found a way to delete the stream #include <WinAPIFiles.au3> If FileExists($sFile & ":Zone.Identifier") Then
_WinAPI_DeleteFile($sFile & ":Zone.Identifier:$DATA") ; this will remove the stream
EndIf

Because I'm not as smart/knowledgeable as you veteran scripters, lol.

##### Share on other sites
19 hours ago, argumentum said:

why not just:

If FileExists($sFile & ":Zone.Identifier") Then FileClose(FileOpen($sFile & ":Zone.Identifier", 2))
FileWrite($sFile & ":Zone.Identifier", "[ZoneTransfer]" & @CRLF & "ZoneId=0" & @CRLF) ; ZoneId=5 would work too EndIf not as clean but it'd solve the problem without the prerequisites. Thanks for sharing @MattHiggs Edit: Found a way to delete the stream #include <WinAPIFiles.au3> If FileExists($sFile & ":Zone.Identifier") Then
_WinAPI_DeleteFile($sFile & ":Zone.Identifier:$DATA") ; this will remove the stream
EndIf

But the script would be better if it didn't have any prerequisites or dependencies, so I updated the script with the code you provided.  You know it's funny, before I began work on this script, I remember doing research in order to determine how Windows flagged a file as "blocked" in order to be able to accomplish what you just showed me, but came up nil after about 30 minutes so I gave up and settled on using the prerequisite methods.  The script in the main post has been updated.

• 1

##### Share on other sites

you can always rewrite _WINAPI_DeleteFIle, extracting only what u need. Basically, that example is just deleting the NTFS Alt Stream.

What is what? What is what.

##### Share on other sites
6 hours ago, Biatu said:

you can always rewrite _WINAPI_DeleteFIle, extracting only what u need. Basically, that example is just deleting the NTFS Alt Stream.

I am not sure what you mean....  I was under the impression that the NTFS Alt Stream is the "flag" which indicates that a file came from the internet and is what "blocks" the file.  Therefore, deleting the Alt Stream would unblock the file, which is the goal.  Can you be a bit more detailed in what you mean?  Examples?

##### Share on other sites

Well, you mentioned that you'd prefer not to have any includes. So, just rewrite the function and pull what is needed from _WinAPI_DeleteFile . Ya know?

And as for Alt Streams...you can store anything in those. Back in the day viruses could be hidden in them, and could be executed directly.

What is what? What is what.

##### Share on other sites
20 hours ago, Biatu said:

Well, you mentioned that you'd prefer not to have any includes. So, just rewrite the function and pull what is needed from _WinAPI_DeleteFile . Ya know?

And as for Alt Streams...you can store anything in those. Back in the day viruses could be hidden in them, and could be executed directly.

Im sorry man.  The more you say the more confused I get.  What I was probably referring to in regards to not wanting to have any includes is the fact that the first version of this script used powershell if the version was high enough to contain the "Unblock-file" cmdlet, and if it wasn't, the script would download and use the streams sysinternals tool to delete the alternate streams instead.  However, I have since completely re-written the script so that it no longer requires these external dependencies.  As in the script can be run completely standalone.  That was the goal, and that has been accomplished.  At this point, my interest in continuing to work on it is non-existent, but you are free to do with it as you like.

## Create an account

Register a new account