How to unzip a file in Powershell?

Powershell

Powershell Problem Overview


I have a .zip file and need to unpack its entire content using Powershell. I'm doing this but it doesn't seem to work:

$shell = New-Object -ComObject shell.application
$zip = $shell.NameSpace("C:\a.zip")
MkDir("C:\a")
foreach ($item in $zip.items()) {
  $shell.Namespace("C:\a").CopyHere($item)
}

What's wrong? The directory C:\a is still empty.

Powershell Solutions


Solution 1 - Powershell

In PowerShell v5+, there is an Expand-Archive command (as well as Compress-Archive) built in:

Expand-Archive c:\a.zip -DestinationPath c:\a

Solution 2 - Powershell

Here is a simple way using ExtractToDirectory from System.IO.Compression.ZipFile:

Add-Type -AssemblyName System.IO.Compression.FileSystem
function Unzip
{
	param([string]$zipfile, [string]$outpath)

	[System.IO.Compression.ZipFile]::ExtractToDirectory($zipfile, $outpath)
}

Unzip "C:\a.zip" "C:\a"

Note that if the target folder doesn't exist, ExtractToDirectory will create it. Other caveats:

See also:

Solution 3 - Powershell

In PowerShell v5.1 this is slightly different compared to v5. According to MS documentation, it has to have a -Path parameter to specify the archive file path.

Expand-Archive -Path Draft.Zip -DestinationPath C:\Reference

Or else, this can be an actual path:

Expand-Archive -Path c:\Download\Draft.Zip -DestinationPath C:\Reference

Expand-Archive Doc

Solution 4 - Powershell

Use Expand-Archive cmdlet with one of parameter set:

Expand-Archive -LiteralPath C:\source\file.Zip -DestinationPath C:\destination
Expand-Archive -Path file.Zip -DestinationPath C:\destination

Solution 5 - Powershell

Hey Its working for me..

$shell = New-Object -ComObject shell.application
$zip = $shell.NameSpace("put ur zip file path here")
foreach ($item in $zip.items()) {
  $shell.Namespace("destination where files need to unzip").CopyHere($item)
}

Solution 6 - Powershell

Use the built in powershell method Expand-Archive

Example

Expand-Archive -LiteralPath C:\archive.zip -DestinationPath C:\

Solution 7 - Powershell

Using expand-archive but auto-creating directories named after the archive:

function unzip ($file) {
	$dirname = (Get-Item $file).Basename
	New-Item -Force -ItemType directory -Path $dirname
	expand-archive $file -OutputPath $dirname -ShowProgress
}

Solution 8 - Powershell

For those, who want to use Shell.Application.Namespace.Folder.CopyHere() and want to hide progress bars while copying, or use more options, the documentation is here:
https://docs.microsoft.com/en-us/windows/desktop/shell/folder-copyhere

To use powershell and hide progress bars and disable confirmations you can use code like this:

# We should create folder before using it for shell operations as it is required
New-Item -ItemType directory -Path "C:\destinationDir" -Force

$shell = New-Object -ComObject Shell.Application
$zip = $shell.Namespace("C:\archive.zip")
$items = $zip.items()
$shell.Namespace("C:\destinationDir").CopyHere($items, 1556)

Limitations of use of Shell.Application on windows core versions:
https://docs.microsoft.com/en-us/windows-server/administration/server-core/what-is-server-core

On windows core versions, by default the Microsoft-Windows-Server-Shell-Package is not installed, so shell.applicaton will not work.

note: Extracting archives this way will take a long time and can slow down windows gui

Solution 9 - Powershell

function unzip {
	param (
		[string]$archiveFilePath,
		[string]$destinationPath
	)

	if ($archiveFilePath -notlike '?:\*') {
		$archiveFilePath = [System.IO.Path]::Combine($PWD, $archiveFilePath)
	}

	if ($destinationPath -notlike '?:\*') {
		$destinationPath = [System.IO.Path]::Combine($PWD, $destinationPath)
	}

	Add-Type -AssemblyName System.IO.Compression
	Add-Type -AssemblyName System.IO.Compression.FileSystem

	$archiveFile = [System.IO.File]::Open($archiveFilePath, [System.IO.FileMode]::Open)
	$archive = [System.IO.Compression.ZipArchive]::new($archiveFile)

	if (Test-Path $destinationPath) {
		foreach ($item in $archive.Entries) {
			$destinationItemPath = [System.IO.Path]::Combine($destinationPath, $item.FullName)

			if ($destinationItemPath -like '*/') {
				New-Item $destinationItemPath -Force -ItemType Directory > $null
			} else {
				New-Item $destinationItemPath -Force -ItemType File > $null

				[System.IO.Compression.ZipFileExtensions]::ExtractToFile($item, $destinationItemPath, $true)
			}
		}
	} else {
		[System.IO.Compression.ZipFileExtensions]::ExtractToDirectory($archive, $destinationPath)
	}
}

Using:

unzip 'Applications\Site.zip' 'C:\inetpub\wwwroot\Site'

Solution 10 - Powershell

ForEach Loop processes each ZIP file located within the $filepath variable

	foreach($file in $filepath)
	{
		$zip = $shell.NameSpace($file.FullName)
		foreach($item in $zip.items())
		{
			$shell.Namespace($file.DirectoryName).copyhere($item)
		}
		Remove-Item $file.FullName
	}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionUli KunkelView Question on Stackoverflow
Solution 1 - PowershellKeith HillView Answer on Stackoverflow
Solution 2 - PowershellMicky BalladelliView Answer on Stackoverflow
Solution 3 - PowershellNIKView Answer on Stackoverflow
Solution 4 - PowershellSaleh RahimzadehView Answer on Stackoverflow
Solution 5 - PowershellAbhijitView Answer on Stackoverflow
Solution 6 - PowershellKellen StuartView Answer on Stackoverflow
Solution 7 - PowershellmikemaccanaView Answer on Stackoverflow
Solution 8 - PowershellMatej RidzonView Answer on Stackoverflow
Solution 9 - Powershelluser1624251View Answer on Stackoverflow
Solution 10 - PowershellPradyumnaView Answer on Stackoverflow