How to unzip a Zip File with Powershell Version 2.0?

20,223

Solution 1

function Expand-ZIPFile($file, $destination)
{
   $shell = new-object -com shell.application
   $zip = $shell.NameSpace($file)
   foreach($item in $zip.items())
   {
      $shell.Namespace($destination).copyhere($item)
   }
}

This leverages Windows's built in zip file support, via the Shell.Application object. To use this, run the following.

>Expand-ZipFile .\Myzip.zip -destination c:\temp\files

Source: http://www.howtogeek.com/tips/how-to-extract-zip-files-using-powershell/

Solution 2

The PowerShell version is just a symptom. It's not the actual cause of the issue. The relevant classes for handling zip archives were added to the System.IO.Compression namespace with .NET Framework 4.5 (a prerequisite for PowerShell v4) and are not available in earlier versions. Install version 4.5 of the .NET Framework and you'll be able to use the IO.Compression.ZipFile class in PowerShell v2 as well.

However, in PowerShell v2

Add-Type -Assembly "System.IO.Compression.Filesystem"

will throw an error that it cannot find the assembly even if you installed .NET Framework 4.5, so you'll need to replace the line with

[Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.Filesystem")

and change the .Net Framework configuration to always use the latest CLR (otherwise PowerShell v2 would use .Net Framework 2.0 instead of 4.5):

reg add HKLM\SOFTWARE\Microsoft\.NETFramework /v OnlyUseLatestCLR /t REG_DWORD /d 1

An alternative that works out of the box even without .NET Framework 4.5 is the Shell.Application COM object, as suggested by @FoxDeploy. Beware, though, that the CopyHere() method runs asynchronously, i.e. it returns immediately without waiting for the actual copy operation to complete. If you want to run it from a script you need to add some sort of delay, because the Shell.Application object is automatically destroyed when the script terminates, thus aborting unfinished copy operations.

Share:
20,223
Raphael
Author by

Raphael

Updated on August 05, 2022

Comments

  • Raphael
    Raphael almost 2 years

    This works for me with PowerShell version 4.0 or higher. But at PowerShell version 2.0 the Add-Type isn't possible (type doesn't exist).

    function unzip {
        Add-Type -Assembly “system.io.compression.filesystem”
    
        [io.compression.zipfile]::ExtractToDirectory("SOURCEPATH\ZIPNAME", "DESTINATIONPATH")
    }
    
  • Raphael
    Raphael almost 8 years
    Then there is the following error message: PS C:\Users\test> [Reflection.Assembly]::LoadWithPartialName("System.IO.Compre‌​ssion.Filesystem") PS C:\Users\test> [io.compression.zipfile]::ExtractToDirectory("C:\WIN_AGENT.z‌​ip", "C:\test\") Unable to find type [io.compression.zipfile]: make sure that the assembly containing this type is loaded. At line:1 char:25 + [io.compression.zipfile] <<<< ::ExtractToDirectory("C:\WIN_AGENT.zip", "C:\test\") + CategoryInfo : InvalidOperation: (io.compression.zipfile:String) [], RuntimeException + FullyQualifiedErrorId : TypeNotFound
  • Raphael
    Raphael almost 8 years
    Unfortunately I am not allowed to change the actual .NET Framework Version. The used .NET Framework Version is 2.0.
  • richb
    richb about 6 years
    This answer is incorrect. First, Add-Type is available in PowerShell V2. Second, [Reflection.Assembly]::LoadWithPartialName("System.IO.Compre‌​ssion.Filesystem") will not work with PowerShell V2, since it uses .NET 2.
  • Ansgar Wiechers
    Ansgar Wiechers about 6 years
    @richb You're right in so far that Add-Type is available in PowerShell v2. However, if you run Add-Type -Assembly 'System.IO.Compression.Filesystem' you'll see that it complains about being unable to find the assembly. Also, it's incorrect that [Reflection.Assembly]::LoadWithPartialName() wouldn't work in PowerShell v2. You just need to make it use the latest CLR version.
  • richb
    richb about 6 years
    Interesting Ansgar I did not know about that. For my use case it's not useful. I wanted a script that runs on vanilla Windows 7. If I'm going to change the registry on each computer to make it work I might as well just install PowerShell 5. I also note comments in that answer about negative side effects of forcing PS 2 to run on .NET 4. Nethertheless it's an interesting hack & thanks for the info.
  • Ansgar Wiechers
    Ansgar Wiechers about 6 years
    If you want a script that'll run on a vanilla Windows 7 you're probably stuck with using the Shell.Application COM object, b/c AFAICS everything else requires some kind of modification to the system (.NET Framework upgrade, 3rd party programs like 7-zip, etc.).