I have a PowerShell (v7.3.7) script that iterates through files and archives them using 7-Zip. When using 7-Zip’s multi-threading option -mmt
, the script takes 180 seconds to execute in my case. However, if I utilize ForEach-Object -Parallel
with -ThrottleLimit 1
, the execution time drops down to 50 seconds. On an interesting sidenote, altering the throttle limit to other numbers doesn’t improve the execution time further, and in fact, increasing it beyond 50% of my logical cores leads to a longer execution time.
I would have thought that 7-Zip’s own multi-threading would be sufficient to fully utilize my cores, but it seems only with -Parallel
(even at -ThrottleLimit 1
), 7-Zip starts using my cores efficiently. I have verified this by disabling -mmt
(using -mmt=off
), which brings the execution time back to its original 180 seconds.
I’m curious as to how PowerShell’s -Parallel
parameter affects 7-Zip’s -mmt
capability. I’ve been at this for a while with ChatGPT4 trying to rule things out, but we’re both (heh) stumped. I suspect this has to be related to how -Parallel
spins up a new runspace and somehow the underlying architecture has an effect on how cpus are made available for the script executed in this namespace. But it shouldn’t.
Has anyone encountered a similar situation or have insights into why this might be happening?
Below is my script for reference:
param(
[Parameter(Mandatory=$true)]
[string]$name,
[Parameter(Mandatory=$true)]
[string]$password
)
# The 7-Zip executable path (modify if necessary)
$7zipPath = "C:\Program Files\7-Zip\7z.exe"
# Ensure 7-Zip is installed
if (!(Test-Path $7zipPath)) {
throw "7-Zip not found at path $7zipPath"
}
$items = Get-ChildItem -Path .\ | Where-Object { $_.Extension -ne ".ps1" }
$timer = Measure-Command {
$items | ForEach-Object -Parallel {
$item = $_
$name = $using:name
$password = $using:password
$7zipPath = $using:7zipPath
$guid = [guid]::NewGuid().ToString()
$zipFileWithoutPassword = "${name}_${guid}.zip"
$zipFileWithPassword = "${name}${guid}.zip"
# Create a non-password protected zip with no compression
$argListNoPassword = "a -tzip ""$zipFileWithoutPassword"" ""$item"" -mx=0 -mmt"
Start-Process -Wait -FilePath "$7zipPath" -ArgumentList $argListNoPassword -NoNewWindow
# Add password protection to the zip using 7-Zip with AES256
$argListWithPassword = "a -tzip ""$zipFileWithPassword"" ""$zipFileWithoutPassword"" -p$password -mem=AES256 -mx=0 -mmt"
Start-Process -Wait -FilePath "$7zipPath" -ArgumentList $argListWithPassword -NoNewWindow
# Remove non-password protected zip
Remove-Item -Path $zipFileWithoutPassword
} -ThrottleLimit 1
}
Write-Host "Total execution time: $($timer.TotalSeconds) seconds"
(Just save this to a .ps1 file and it will zip everything in the current folder when executed, excluding .ps1 files. Run it with: ./the_script.ps1 archive-entry somepassword
.)
PowerShell has had the ability to both create and extract contents from ZIP files for quite some time. Even so, PowerShell’s native support for handling ZIP files is somewhat limited. Fortunately, we have a workaround to overcome these limitations.
PowerShell’s Native Zip File Support
Compress-Archive -Path C:\Scripts\*.txt -DestinationPath C:\Scripts\Temp\Text.zip
You can see the command and the resulting ZIP file in Figure 1.
Figure 1. This is how you create a ZIP file in PowerShell.
Extracting a ZIP file’s contents is just as easy. You would use a cmdlet named Expand-Archive, requiring both the source and destination paths. For example, if you wanted to extract the contents of the recently created ZIP file and place its contents in the C:\Scripts\Extract folder, this would be the command:
Expand-Archive -Path C:\Scripts\Temp\Text.zip -DestinationPath C:\Scripts\Extract
You can see the command and the extracted files in Figure 2.
Figure 2. PowerShell can extract a ZIP file’s contents.
As you can see, the Compress-Archive and Expand-Archive cmdlets are simple to use. Nevertheless, they come with certain limitations.
Firstly, native cmdlets use UTF-8 encoding. If you open a ZIP file created by another utility that uses a different encoding, the filenames may be incorrect.
Secondly, there is a size cap of 2 GB for compressed archives. The Compress-Archive cmdlet also ignores hidden files and folders.
However, the most notable constraint is the absence of . As a result, you cannot create or access a password-protected ZIP using Compress-Archive and Expand-Archive cmdlets.
An Alternative Solution
The best workaround I have found involves using the 7-Zip PowerShell module. For those unfamiliar, 7-Zip is a freely available open-source tool for creating and extracting archive files. The named 7Zip4PowerShell enables you to access 7-Zip functionality directly from the command line.
Here is the command used to install the 7-Zip PowerShell module:
Install-Module -Name 7Zip4PowerShell
You can see what the installation process looks like in Figure 3.
Figure 3. This is how you install the 7Zip4PowerShell module.
Creating a ZIP archive using 7Zip4PowerShell is just as easy as it is with native PowerShell. The cmdlet you use is Compress-7Zip.
By the way, if you are curious about the list of the cmdlets included in the 7Zip4PowerShell module, you can use this command:
Get-Command -Module 7Zip4PowerShell
Figure 4. You can use the Get-Command and Get-Help cmdlets to familiarize yourself with the 7Zip4PowerShell module’s cmdlets.
At any rate, if you wanted to create a ZIP file called C:\Scripts\Temp\Text.zip containing all the text files located in the C:\Scripts folder, you would use this command:
Figure 5. This is how you create a compressed archive using 7-Zip.
The Compress-7Zip cmdlet does indeed support a path parameter to specify what you want to include in the archive. In all honesty, though, I encountered some difficulties in getting the cmdlet to do what I wanted (it’s been a long day, maybe I’m just tired). So, I devised a workaround using the Get-ChildItem cmdlet to compile a list of files to include in the archive, which I then passed to the Compress-7Zip cmdlet via a pipeline operation. I used the -ArchiveFileName and the -Format parameters with the Compress-7Zip cmdlet. Technically, the -Format parameter isn’t required, but I included it to illustrate that 7-Zip supports various archive types beyond ZIP files.
Expand-7Zip -ArchiveFileName C:\Scripts\Temp\Text.zip -TargetPath C:\Scripts\Extract -Password ‘ABC’
You can this in action in Figure 6.
Figure 6. This is how you create and open a password-protected archive.
About the Author(s)
Brien Posey is a bestselling technology author, a speaker, and a 20X Microsoft MVP. In addition to his ongoing work in IT, Posey has spent the last several years training as a commercial astronaut candidate in preparation to fly on a mission to study polar mesospheric clouds from space.
### Custom Code Starts ####################################################################################################################
### Install 7-Zip
“/i `”$Global:WorkingFolder\$AppDeploy_Package`” /qn /norestart /L `”$Global:Logpath\$AppDeploy_Name-install.log`””
“Initiating installation of $AppDeploy_Name”
### Custom Code Ends ####################################################################################################################

Table of contents
- Introduction to PowerShell Unzip
- Understanding the PowerShell unzip command Expand-Archive
- How to unzip a file using PowerShell?
- How to extract all zip files in a folder using PowerShell
- How do I unzip multiple files in PowerShell?
- Using the ExtractToDirectory Method to Unzip
- How do you read the content of a zip file without unzipping it?
- How to extract a password-protected zip file in PowerShell?
- Troubleshooting Common Issues with PowerShell Unzip
- Conclusion
Introduction to PowerShell Unzip
PowerShell is a powerful scripting language that allows you to automate many different tasks, including file extraction and compression. With PowerShell, you can easily extract files from compressed archives, as well as create your own compressed files. PowerShell uses a set of cmdlets (pronounced “command-lets”) to perform these operations. A cmdlet is a lightweight command that performs a specific action. In the case of file extraction and compression, PowerShell provides Expand-Archive and Compress-Archive cmdlets that you can use to automate these tasks.
Understanding the PowerShell unzip command Expand-Archive
PowerShell unzip refers to the process of extracting files and folders from a ZIP archive using PowerShell commands. The Expand-Archive cmdlet is used to extract files from a compressed archive. To use the PowerShell unzip command, you’ll need to know the path and name of the compressed archive you want to extract files from. You’ll also need to specify the path to which you want to extract the files. The Expand-Archive cmdlet is a built-in PowerShell command that allows you to extract files from a ZIP archive. This cmdlet is part of Microsoft.PowerShell.Archive module. The Expand-Archive cmdlet was introduced in Windows PowerShell 5.1. You don’t need to install any additional software to use PowerShell Unzip. It’s already installed on your Windows computer.
Now that you understand how the PowerShell unzip command, Expand-Archive. Let’s take a look at how to use PowerShell to extract files from a compressed archive. To use the Expand-Archive cmdlet, you need to specify the path to the ZIP file and the destination path where the extracted files will be stored. The syntax for expand-archive in PowerShell is simple:
Expand-Archive [-Path] <string> [-DestinationPath] <string> [-Force] [-WhatIf] [-Confirm] [-PassThru] [-LiteralPath <string>]
#Expand-Archive -LiteralPath PathToZipFile -DestinationPath PathToDestination Expand-Archive -Path "C:\Temp\LogsArchive.zip" -DestinationPath "C:\Temp\Logs"
This command will extract all the files from the existing zipped file located at “C:\Temp\LogsArchive.zip” and place them in the folder located at “C:\Temp\Logs”. You can verify that the files were extracted correctly by navigating to the destination directory and checking that the files are there. Use quotations around the path when the file path contains a space.

If the zip file is located in the current folder, we just need to specify the zip file using LiteralPath
or Path
parameter, and optionally, the DestinationPath
parameter value. If the “DestinationPath” parameter is not provided, it extracts the archive to the current directory.
Expand-Archive -LiteralPath ".\Scripts.zip"
If you want to overwrite destination files during the extraction process, you can use the -Force
parameter:
Expand-Archive -Path 'C:\Archives\Example.zip' -DestinationPath 'C:\ExtractedFiles' -Force
By including the -Force
parameter, PowerShell will overwrite existing files with the extracted files, if necessary.
If you find yourself needing to extract multiple ZIP files in a directory, you don’t need to do this one by one. Instead, you can use PowerShell! Let’s say you want to extract all the ZIP files present in the directory “C:\Archives”. You will first need to obtain all the ZIP files in the directory and then extract them one by one. The Get-ChildItem
cmdlet, and we’ll utilize a foreach
loop to iterate through each file.
How do I unzip multiple files in PowerShell? Here is the PowerShell script to extract all zip files in a Folder:
Get-ChildItem "C:\Archives" -Filter *.zip | ForEach { Expand-Archive -Path $_.FullName -DestinationPath "C:\Extracted" -Force }

The above command uses the wildcard characters to get all zip files and extract them from the folder “C:\Archives” to the “C:\Extracted”.
How do I unzip multiple files in PowerShell?
Instead of all files in a directory, You can supply specific zip files to extract to a specific folder:
#Parameters $FilesToExtract = @("C:\Archives\Backup-Set1.zip","C:\Archives\Backup-Set2.zip", "C:\Archives\Backup-Set3.zip") $DestinationDirectory = "C:\Extracted" # Loop through each file and extract it ForEach ($ZipFile in $FilesToExtract) { #Frame Folder to Extract $ExtractedFolderName = $ZipFile -replace ".zip$" $ExtractedFolderPath = Split-Path -Path $ExtractedFolderName -Leaf $DestinationPath = Join-Path -Path $DestinationDirectory -ChildPath $ExtractedFolderPath # Create the destination folder if it doesn't exist If (-not (Test-Path -Path $DestinationPath)) { New-Item -Path $DestinationPath -ItemType Directory | Out-Null } #Extract Each Archive to the Destination Folder Expand-Archive -Path $ZipFile -DestinationPath $DestinationPath -Force }
Another method to unzip files using PowerShell is by using the ZipFile.ExtractToDirectory method is available in the .NET framework. This method allows you to extract files from a ZIP archive using the System.IO.Compression.ZipFile class. It is particularly useful for lower versions of .NET, such as Windows PowerShell 5.1.
Syntax of ZipFile.ExtractToDirectory
Add-Type -AssemblyName System.IO.Compression.FileSystem [System.IO.Compression.ZipFile]::ExtractToDirectory(<SourceFile>, <DestinationPath>)
In the syntax, the <SourceFile>
parameter specifies the path to the ZIP file, and the <DestinationPath>
parameter specifies the folder where the extracted files will be stored.
Examples of Using ZipFile.ExtractToDirectory
Add-Type -AssemblyName System.IO.Compression.FileSystem [System.IO.Compression.ZipFile]::ExtractToDirectory("C:\Archives\Example.zip", "C:\ExtractedFiles")
Overwriting existing files during extraction
To overwrite existing files during the extraction process, you can include a third parameter, true
, in the ExtractToDirectory
method:
Add-Type -AssemblyName System.IO.Compression.FileSystem [System.IO.Compression.ZipFile]::ExtractToDirectory("C:\Archives\Example.zip", "C:\ExtractedFiles", $true)
By specifying $true
, PowerShell will overwrite existing files with the archive’s contents if necessary.
How do you read the content of a zip file without unzipping it?
You can get the contents of the file without extracting it. Here is how:
Add-Type -AssemblyName System.IO.Compression.FileSystem #Parameters $ZipFilePath = "C:\Temp\Archive.zip" $FileName = "Output.txt" #Get Contents of the Zip File $ZipContents = [System.IO.Compression.ZipFile]::OpenRead($ZipFilePath) # Get the specific entry (file) from the zip archive $SpecificFile = $ZipContents.GetEntry($FileName) #Get Contents of the File $StreamReader = [System.IO.StreamReader]::new($SpecificFile.Open()).ReadToEnd() | Write-Host
How do I extract specific files from a zip file? To extract a specific file from the zip file, use this PowerShell script:
Add-Type -AssemblyName System.IO.Compression.FileSystem #Parameters $ZipFilePath = "C:\Temp\Archive.zip" $SpecificFileName = "Output.txt" $DestinationFilePath = "C:\Temp\Output.txt" Try { #Get Contents of the Zip File $ZipContents = [System.IO.Compression.ZipFile]::OpenRead($ZipFilePath) # Get the specific entry (file) from the zip archive $SpecificFile = $ZipContents.GetEntry($SpecificFileName) #Get Contents of the File $inputStream = $SpecificFile.Open() $outputStream = [System.IO.File]::Create($DestinationFilePath) # Copy the content from the input stream to the output stream $inputStream.CopyTo($outputStream) $inputStream.Close() $outputStream.Close() } Finally { $ZipContents.Dispose() }
The native PowerShell methods don’t support extracting password-protected archives. So, You have to use 3rd party modules like 7zip to extract a password-protected zip file in PowerShell. Here are the steps:
Step 1: Install the “7Zip4Powershell” module
Install-Module -Name 7Zip4Powershell
To find a list of all supported commands from the module, use: Get-Command -Module 7Zip4PowerShell.
Use the Expand-7Zip cmdlet to extract the file. Set the ArchiveFileName, TargetPath, and SecurePassword to define your parameters.
Expand-7Zip -ArchiveFileName 'C:\Archives\Backup.zip' -TargetPath 'C:\Files\' -SecurePassword (Read-Host "Enter password" -AsSecureString)
This will prompt for a password for the archive.
Troubleshooting Common Issues with PowerShell Unzip
While PowerShell unzip operations are generally straightforward, you may encounter some common issues. Here are a few troubleshooting tips to help you overcome these challenges:
- Verify that the ZIP file path and the destination folder path are correct and accessible.
- Check if the ZIP file is not corrupted or encrypted with a password that requires additional steps for extraction.
- Ensure you have the necessary permissions to extract files from the ZIP archive and write them in the destination folder.
- Update your PowerShell version and modules to the latest versions to benefit from bug fixes and improvements that may resolve any known issues.
Conclusion
How to extract zip from the command line?
You can use the Expand-Archive
cmdlet to extract a ZIP file using PowerShell. Here’s an example of the command you can use: “Expand-Archive -Path 'C:\path\to\file.zip' -DestinationPath 'C:\path\to\extract'
“. Replace the paths with the actual paths to your ZIP file and the destination folder where you want to extract the files.
How to extract 7-Zip files from the command line?
To extract 7-Zip files from the command line, you can use the 7z command-line utility provided by 7-Zip. Here’s how you can extract 7-Zip files using the command line: 7z x archive.7z -oC:\Destination
How do I create a zip file in PowerShell?
To create a zip file in PowerShell, you can Open PowerShell by searching for it in the Start menu, and use the Compress-Archive cmdlet. Here’s an example of how to do it:Compress-Archive -Path C:\PathToFiles -DestinationPath 'C:\Archives\MyArchive.zip' -CompressionLevel NoCompression
Can I overwrite existing files when unzipping with PowerShell?
Yes, you can use the -Force parameter with the Expand-Archive command to overwrite existing files when unzipping.
Is it possible to unzip files to the same directory they are located in?
Yes, you can unzip files to the same directory by omitting the -DestinationPath parameter or setting it to the directory of the zip file. For example, To extract the files and subfolders of a zip file to the root directory, use:$ZipFilePath = "C:\Temp\Logs\Logs1.zip"
Expand-Archive -Path $ZipFilePath -DestinationPath (Get-Item $ZipFilePath).DirectoryName -Force
Can I unzip a specific file from a zip archive?
PowerShell’s Expand-Archive cmdlet does not directly support extracting specific files from an archive. As a workaround, you can extract all files to a temporary directory and then move the specific file(s) you need to your desired location.
Can I unzip password-protected ZIP files using PowerShell?
The built-in Expand-Archive
cmdlet does not support unzipping password-protected ZIP files. However, you can use third-party modules or libraries that support password-protected ZIP files. For example, you can use the 7Zip4PowerShell module: Expand-7Zip -ArchiveFileName "C:\Archives\protected.zip" -Password "your_password" -TargetPath "C:\ExtractedFiles"
2.4.0
Powershell module for creating and extracting 7-Zip archives
Minimum PowerShell version
There is a newer prerelease version of this module available.
See the version list below for details.
Install-Module -Name 7Zip4Powershell -RequiredVersion 2.4.0
Install-PSResource -Name 7Zip4Powershell -Version 2.4.0
Owners
-
thoemmi
Copyright
2013-2021 Thomas Freudenberg
Version | Downloads | Last updated |
---|---|---|
2.5.0 | 184,744 | |
2.4.1-beta0008 | 735 | |
2.4.0 (current version) | 5,369,315 | |
2.3.0 | 4,083,170 | |
2.2.0 | 3,467,926 | |
2.1.1-beta0012 | 672 | |
2.1.1-beta0011 | 654 | |
2.1.0 | 803,692 | |
2.0.1-beta0007 | 878 | |
2.0.1-beta0004 | 890 | |
2.0.0 | 1,664,642 | |
2.0.0-beta0009 | 890 | |
2.0.0-beta0008 | 871 | |
1.13.0 | 603,965 | |
1.12.0 | 32,168 | |
1.11.0 | 1,269 | |
1.10.0.0 | 123,257 | |
1.9.0 | 507,003 | |
1.8.0 | 101,048 | |
1.7.1 | 1,515 | |
1.7.0 | 181 | |
1.6.0 | 936 | |
1.5.0 | 155 | |
1.4.0 | 219 | |
1.3.0 | 345 | |
1.2.0 | 198 | |
1.1.0 | 179 |
Join our monthly Unpacking Software livestream to hear about the latest news, chat and opinion on packaging, software deployment and lifecycle management!
Join the Chocolatey Team on our regular monthly stream where we put a spotlight on the most recent Chocolatey product releases. You’ll have a chance to have your questions answered in a live Ask Me Anything format.
Join us for the Chocolatey Coding Livestream, where members of our team dive into the heart of open source development by coding live on various Chocolatey projects. Tune in to witness real-time coding, ask questions, and gain insights into the world of package management. Don’t miss this opportunity to engage with our team and contribute to the future of Chocolatey!
Webinar from
Wednesday, 17 January 2024
Join the Chocolatey Team as we discuss all things Community, what we do, how you can get involved and answer your Chocolatey questions.
Watch The Replays
Webinar Replay from
Wednesday, 30 March 2022
At Chocolatey Software we strive for simple, and teaching others. Let us teach you just how simple it could be to keep your 3rd party applications updated across your devices, all with Intune!
Livestream from
Thursday, 9 June 2022
Join James and Josh to show you how you can get the Chocolatey For Business recommended infrastructure and workflow, created, in Azure, in around 20 minutes.
Livestream from
Thursday, 04 August 2022
Join Paul and Gary to hear more about the plans for the Chocolatey CLI in the not so distant future. We’ll talk about some cool new features, long term asks from Customers and Community and how you can get involved!
Livestreams from
October 2022