How to unzip a file in Powershell?
Sophia Terry
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.
10 Answers
In PowerShell v5+, there is an Expand-Archive command (as well as Compress-Archive) built in:
Expand-Archive c:\a.zip -DestinationPath c:\a 8 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:
- Existing files will not be overwritten and instead trigger an IOException.
- This method requires at least .NET Framework 4.5, available for Windows Vista and newer.
- Relative paths are not resolved based on the current working directory, see Why don't .NET objects in PowerShell use the current directory?
See also:
- How to Compress and Extract files (Microsoft Docs)
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:\ReferenceOr else, this can be an actual path:
Expand-Archive -Path c:\Download\Draft.Zip -DestinationPath C:\Reference 1 Use Expand-Archive cmdlet with one of parameter set:
Expand-Archive -LiteralPath C:\source\file.Zip -DestinationPath C:\destinationExpand-Archive -Path file.Zip -DestinationPath C:\destination 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)
} 2 Use the built in powershell method Expand-Archive
Example
Expand-Archive -LiteralPath C:\archive.zip -DestinationPath C:\ 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
} 3 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:
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:
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
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' 1 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 }