Extract Multiple ZIP Files Using PowerShell

Managing compressed files is a common task for system administrators, developers, and power users. Whether you’re dealing with software packages, backups, or log archives, you’ll often encounter situations where you need to extract multiple ZIP files at once.

Manually unzipping dozens (or hundreds) of files through Windows Explorer is time-consuming and error-prone. Thankfully, with PowerShell, you can automate this process efficiently.

In this guide, we’ll explore how to extract multiple ZIP files using PowerShell, including an option to select the source and destination directories interactively. We’ll also cover automation best practices, error handling, and tips for bulk extraction.


Why Use PowerShell for Extracting ZIP Files?

  • Automation – Extract hundreds of ZIP files in one go.
  • Flexibility – Choose directories dynamically at runtime.
  • Control – Decide whether to overwrite, skip, or log conflicts.
  • Reusability – Save scripts and run them on multiple machines.

PowerShell provides the Expand-Archive cmdlet (available in PowerShell 5.1+) and also allows .NET methods for advanced scenarios.


Step 1: Extract a Single ZIP File with PowerShell

The simplest example:

Expand-Archive -Path "C:\Source\file.zip" -DestinationPath "C:\Destination"

This extracts file.zip into C:\Destination.

If the destination already contains files, use -Force to overwrite:

Expand-Archive -Path "C:\Source\file.zip" -DestinationPath "C:\Destination" -Force

Step 2: Extract Multiple ZIP Files from a Directory

To handle all ZIP files in a folder:

$Source = "C:\SourceZips"
$Destination = "C:\ExtractedFiles"

Get-ChildItem -Path $Source -Filter *.zip | ForEach-Object {
    $ZipFile = $_.FullName
    $DestPath = Join-Path $Destination $_.BaseName
    Expand-Archive -Path $ZipFile -DestinationPath $DestPath -Force
}

Explanation:

  • Get-ChildItem fetches all .zip files.
  • Each ZIP is extracted into a subfolder named after the ZIP file.
  • -Force ensures overwriting.

Step 3: Interactive Script with Directory Selection

Instead of hardcoding paths, we can prompt the user for source and destination directories.

Add-Type -AssemblyName System.Windows.Forms

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

# Function to select folder
function Select-Folder($Message) {
    $dialog = New-Object System.Windows.Forms.FolderBrowserDialog
    $dialog.Description = $Message
    $dialog.RootFolder = 'MyComputer'
    if ($dialog.ShowDialog() -eq 'OK') {
        return $dialog.SelectedPath
    } else {
        Write-Output "No folder selected. Exiting script."
        exit
    }
}

# Prompt for source and destination
$Source = Select-Folder "Select the folder containing ZIP files:"
$Destination = Select-Folder "Select the destination folder for extraction:"

# Get ZIP files
$ZipFiles = Get-ChildItem -Path $Source -Filter *.zip
$Total = $ZipFiles.Count
if ($Total -eq 0) {
    [System.Windows.Forms.MessageBox]::Show("No ZIP files found in $Source", "No Files", "OK", "Warning")
    exit
}

# Create Progress Form
$form = New-Object System.Windows.Forms.Form
$form.Text = "Extracting ZIP Files"
$form.Size = New-Object System.Drawing.Size(500,150)
$form.StartPosition = "CenterScreen"

$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,20)
$label.Size = New-Object System.Drawing.Size(460,20)
$form.Controls.Add($label)

$progressBar = New-Object System.Windows.Forms.ProgressBar
$progressBar.Location = New-Object System.Drawing.Point(10,50)
$progressBar.Size = New-Object System.Drawing.Size(460,30)
$progressBar.Minimum = 0
$progressBar.Maximum = $Total
$form.Controls.Add($progressBar)

$form.Show()

# Extract ZIPs with progress
$Count = 0
foreach ($Zip in $ZipFiles) {
    $Count++
    $label.Text = "Extracting: $($Zip.Name) ($Count of $Total)"
    $progressBar.Value = $Count
    $form.Refresh()

    $DestPath = Join-Path $Destination $Zip.BaseName
    try {
        Expand-Archive -Path $Zip.FullName -DestinationPath $DestPath -Force
    } catch {
        [System.Windows.Forms.MessageBox]::Show("Failed to extract $($Zip.Name): $_", "Error", "OK", "Error")
    }
    Start-Sleep -Milliseconds 300  # Just to make progress visible
}

$form.Close()
[System.Windows.Forms.MessageBox]::Show("Extraction completed! $Total files processed.", "Done", "OK", "Information")

Step 4: Advanced Automation (Error Handling & Logging)

In production environments, you’ll want error handling and logs:

$LogFile = "C:\ExtractLog.txt"

Get-ChildItem -Path $Source -Filter *.zip | ForEach-Object {
    try {
        $ZipFile = $_.FullName
        $DestPath = Join-Path $Destination $_.BaseName
        Expand-Archive -Path $ZipFile -DestinationPath $DestPath -Force
        Add-Content -Path $LogFile -Value "SUCCESS: Extracted $ZipFile to $DestPath"
    } catch {
        Add-Content -Path $LogFile -Value "ERROR: Failed to extract $ZipFile - $_"
    }
}

Now, every extraction attempt is logged.


Step 5: Schedule Automatic Extraction

If you receive ZIP files regularly (e.g., nightly backups), schedule this script to run automatically:

  1. Save the script as ExtractZips.ps1.
  2. Open Task SchedulerCreate Task.
  3. Trigger: Daily / At logon / At startup.
  4. Action: Start a programpowershell.exe -File "C:\Scripts\ExtractZips.ps1".

This ensures automated extraction without manual effort.


Extra Tips

  1. Password-Protected ZIPs
    • PowerShell doesn’t natively support password-protected ZIPs. Use 7-Zip CLI integration instead.
    & "C:\Program Files\7-Zip\7z.exe" x "C:\Source\secure.zip" -pYourPassword -oC:\Destination -y
  2. Preserve Folder Hierarchy
    • If your ZIP files are in nested folders, use -Recurse with Get-ChildItem.
  3. Overwrite Handling
    • Without -Force, PowerShell will throw an error if files already exist.
    • Use -Force to replace or handle exceptions with try/catch.
  4. Compression as Reverse Operation
    • PowerShell can also create ZIP files:
    Compress-Archive -Path "C:\Data\*" -DestinationPath "C:\Backups\data.zip" -Force

Conclusion

Extracting multiple ZIP files manually is inefficient, but PowerShell automation makes the process seamless. By leveraging the Expand-Archive cmdlet along with directory selection prompts, you can create a reusable script that:

  • Extracts all ZIP files in bulk
  • Lets users select source and destination dynamically
  • Provides error handling and logging
  • Can be scheduled for automation

This approach saves time, prevents errors, and scales easily for both personal and enterprise use.

About the author: PShivkumar

With over 12 years of experience in IT and multiple certifications from Microsoft, our creator brings deep expertise in Exchange Server, Exchange Online, Windows OS, Teams, SharePoint, and virtualization. Scenario‑first guidance shaped by real incidents and recoveries Clear, actionable breakdowns of complex Microsoft ecosystems Focus on practicality, reliability, and repeatable workflows Whether supporting Microsoft technologies—server, client, or cloud—his work blends precision with creativity, making complex concepts accessible, practical, and engaging for professionals across the IT spectrum.

View all posts →

Comments

📝 Leave a Comment