Is it possible to create a zip archive using PowerShell?
24 Answers
PowerShell v5.0 adds Compress-Archive
and Expand-Archive
cmdlets. The linked pages have full examples, but the gist of it is:
# Create a zip file with the contents of C:\Stuff\
Compress-Archive -Path C:\Stuff -DestinationPath archive.zip
# Add more files to the zip file
# (Existing files in the zip file with the same name are replaced)
Compress-Archive -Path C:\OtherStuff\*.txt -Update -DestinationPath archive.zip
# Extract the zip file to C:\Destination\
Expand-Archive -Path archive.zip -DestinationPath C:\Destination

- 14,956
- 14
- 78
- 115
-
12PowerShell v5.0 has been officially released now. It also comes with Windows 10. – Ohad Schneider Apr 13 '16 at 16:18
-
Now available here: https://www.microsoft.com/en-us/download/details.aspx?id=50395 – starlocke Oct 31 '16 at 15:40
-
It's also easier to install via Chocolatey, though it still requires reboot - https://chocolatey.org/packages/PowerShell – starlocke Oct 31 '16 at 15:50
-
3From Paragraph 2 of `Compress-Archive` Description: "...the maximum file size that you can compress by using Compress-Archive is currently 2 GB. This is a limiation of underlying API" However, if you use `System.IO.Compression.ZipFile` you can bypass this limitation. – AMissico Nov 09 '16 at 01:58
-
3The 2GB limit was inherited from `System.IO.Compression.ZipFile`. If the .NET framework you are using does not have this limit, the CmdLet should not hit this limit. I verified in the code. – TravisEz13 Jan 07 '17 at 02:36
-
Use `-OutputPath` instead of `-DestinationPath` – Pramod Oct 16 '17 at 14:00
-
2@Pramod there is no `-OutputPath` parameter. – BrainSlugs83 Mar 22 '18 at 20:01
-
`Compress-Archive` builds a zip file with backslashes instead of forward ones. Did I miss something? The resulting zip file is a pain to use on other OSes. – akim Apr 25 '18 at 15:21
-
I tried a lot of things. Using .NET framework as one of the ways to do this. But this is by far the solution that has given me the least problems. Only drawback is the 2Gb limit – Squazz Oct 15 '18 at 09:05
-
`Compress-Archive` [creates broken archives](https://github.com/PowerShell/Microsoft.PowerShell.Archive/issues/11), sadly this issue hasn't been fixed in 2 years since it was reported, and a pull request has been ignored for 6 months. – Roman Starkov Jan 29 '19 at 17:51
-
It appears the code to fix this slash/backslash broken archive problem https://github.com/PowerShell/Microsoft.PowerShell.Archive/pull/62 was merged on 2019-02-19. – Scott Centoni Mar 07 '19 at 19:15
-
Thanks for these examples. Is it also possible to e.g. get all xml files from multiple child folders, and zip them? I just created https://stackoverflow.com/questions/71934727/get-xml-files-from-multiple-folders-and-zip-them-into-one-archive-in-powershell and am failing with this. Would be great to see an example / answer :) – Dominik Apr 20 '22 at 07:02
A pure PowerShell alternative that works with PowerShell 3 and .NET 4.5 (if you can use it):
function ZipFiles( $zipfilename, $sourcedir )
{
Add-Type -Assembly System.IO.Compression.FileSystem
$compressionLevel = [System.IO.Compression.CompressionLevel]::Optimal
[System.IO.Compression.ZipFile]::CreateFromDirectory($sourcedir,
$zipfilename, $compressionLevel, $false)
}
Just pass in the full path to the zip archive you would like to create and the full path to the directory containing the files you would like to zip.
-
1Does this actually need Powershell 3.0, or just .net 4.5? Looks very light on actual powershell features to me, instead just being .net programming. – bwerks Aug 29 '13 at 18:43
-
@bwerks see the 'edit' portion [here](http://stackoverflow.com/a/12978117/1751302) – noam Sep 18 '13 at 14:30
-
I was looking for a way to just compress a single large file, but apparently there isn't a method for this. I had to write code that would create a new directory, copy the single file there, compress that directory to a new zip file, then delete the directory to clean up. – Baodad Aug 29 '14 at 15:50
-
Should've read that I needed the full path. Boy that was confusing! BTW this should be the accepted answer – Kellen Stuart Oct 19 '16 at 21:50
-
-
@Baodad Uh there is a method for this. I don't know why no one looks at the docs. Creating a zip: https://learn.microsoft.com/en-us/dotnet/api/system.io.compression.zipfile.open?view=netframework-4.5 Adding a single file to the zip: https://learn.microsoft.com/en-us/dotnet/api/system.io.compression.zipfileextensions.createentryfromfile?view=netframework-4.5 – Pluto Sep 18 '18 at 21:29
If you head on over to CodePlex and grab the PowerShell Community Extensions, you can use their write-zip
cmdlet.
Since
CodePlex is in read-only mode in preparation for shutdown
you can go to PowerShell Gallery.

- 6,295
- 1
- 15
- 33

- 200,371
- 61
- 386
- 320
-
124Yep, and it uses 7z as the core library for most of its compression cmdlets. I know, becaues I implemented it ;) +1 – x0n Jul 21 '09 at 01:10
-
1lol nice work, x0n. I imlpemented the feed store provider in PSCX. Slightly less practical but tonnes of fun. :) – Matt Hamilton Jul 21 '09 at 02:37
-
1
-
3
-
10Powershell 5 comes with a Compress-Archive cmdlets that creates .zip https://blogs.technet.microsoft.com/heyscriptingguy/2015/08/13/new-feature-in-powershell-5-compress-files/ – Benoit Patra Feb 04 '17 at 07:45
-
1"Compress-Archive" is not that great: it has an input file size limitation of 2 GiB. – Kevin Meier Jul 27 '18 at 07:09
-
Remember that Powershell is .NET ... .NET has had the ZipFile class since implementation 4.5. Just use Reflection and you can grab the Compression.FileSystem assembly needed. Very simple. https://docs.microsoft.com/en-us/dotnet/api/system.io.compression.zipfile?redirectedfrom=MSDN&view=netframework-4.7.2 https://docs.microsoft.com/en-us/dotnet/api/system.io.compression.zipfile.createfromdirectory?view=netframework-4.7.2 https://blogs.technet.microsoft.com/heyscriptingguy/2015/03/09/use-powershell-to-create-zip-archive-of-folder I believe the accepted answer should be changed to another – DtechNet Oct 12 '18 at 20:28
-
1This is no longer a good accepted answer. However, users will find the thread helpful with the proper answers and various alternatives being posted elsewhere. – DtechNet Oct 12 '18 at 20:31
-
Why bloat your computer with extensions, when you can use the built in Compress-Archive – nivs1978 Mar 10 '20 at 14:42
A native way with latest .NET 4.5 framework, but entirely feature-less:
Creation:
Add-Type -Assembly "System.IO.Compression.FileSystem" ;
[System.IO.Compression.ZipFile]::CreateFromDirectory("c:\your\directory\to\compress", "yourfile.zip") ;
Extraction:
Add-Type -Assembly "System.IO.Compression.FileSystem" ;
[System.IO.Compression.ZipFile]::ExtractToDirectory("yourfile.zip", "c:\your\destination") ;
As mentioned, totally feature-less, so don't expect an overwrite flag.
UPDATE: See below for other developers that have expanded on this over the years...

- 4,870
- 3
- 42
- 60
-
-
This should be the accepted answer in order of date posted and precedent. As to your updated comment - there is truly a vast number of ways to do this now. I am faced with needing this functionality and I'm on PowerShell 4 the first thing I found is the native way. This was a good question in 2009. I still think there could have been further research presented in the question when originally asked. – DtechNet Oct 12 '18 at 20:35
Install 7zip (or download the command line version instead) and use this PowerShell method:
function create-7zip([String] $aDirectory, [String] $aZipfile){
[string]$pathToZipExe = "$($Env:ProgramFiles)\7-Zip\7z.exe";
[Array]$arguments = "a", "-tzip", "$aZipfile", "$aDirectory", "-r";
& $pathToZipExe $arguments;
}
You can the call it like this:
create-7zip "c:\temp\myFolder" "c:\temp\myFolder.zip"

- 3,149
- 4
- 29
- 31
-
6If 7zip is in your path then all you need to write is "& 7z c:\temp\myFolder c:\temp\myFolder.zip" – aboy021 Jun 24 '13 at 02:17
-
5If you don't want to install it, you can download the command line version instead. (Just look on 7-zip's Download page.) It's just an executable, and the command syntax is the same. The executable is a different name, though; it's 7za.exe for some reason. I've done this on a number of projects and have never been disappointed. – jpmc26 May 08 '14 at 19:50
-
I tried with .net and Powershell tools for way too long until going the 7zip path which worked right away. Simple foreach loop on $file does the trick ```& "C:\Program Files\7-Zip\7z.exe" a -tzip ($file.FullName+".zip") $file.FullName``` – SebK Nov 09 '18 at 09:14
Lot has changed since the initial answer was posted. Here are some of the latest examples using Compress-Archive command.
Command to create new archive file, Draft.zip
, by compressing two files, Draftdoc.docx
and diagram2.vsd
, specified by the Path
parameter. The compression level specified for this operation is Optimal.
Compress-Archive -Path C:\Reference\Draftdoc.docx, C:\Reference\Images\diagram2.vsd -CompressionLevel Optimal -DestinationPath C:\Archives\Draft.Zip
Command to creates new archive file, Draft.zip
, by compressing two files, Draft doc.docx
and Diagram [2].vsd
, specified by the LiteralPath
parameter. The compression level specified for this operation is Optimal.
Compress-Archive -LiteralPath 'C:\Reference\Draft Doc.docx', 'C:\Reference\Images\Diagram [2].vsd' -CompressionLevel Optimal -DestinationPath C:\Archives\Draft.Zip
Command to create new archive file, Draft.zip
, in the C:\Archives
folder. The new archive file contains every file in the C:\Reference folder, because a wildcard character was used in place of specific file names in the Path parameter.
Compress-Archive -Path C:\Reference\* -CompressionLevel Fastest -DestinationPath C:\Archives\Draft
Command creates an archive from an entire folder, C:\Reference
Compress-Archive -Path C:\Reference -DestinationPath C:\Archives\Draft
PowerShell appends the .zip
extension to the file name automatically.

- 506
- 8
- 10
Edit two - This code is an ugly, ugly kluge from olden days. You do not want it.
This compresses the contents of .\in
to .\out.zip
with System.IO.Packaging.ZipPackage following the example here
$zipArchive = $pwd.path + "\out.zip"
[System.Reflection.Assembly]::Load("WindowsBase,Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
$ZipPackage=[System.IO.Packaging.ZipPackage]::Open($zipArchive,
[System.IO.FileMode]"OpenOrCreate", [System.IO.FileAccess]"ReadWrite")
$in = gci .\in | select -expand fullName
[array]$files = $in -replace "C:","" -replace "\\","/"
ForEach ($file In $files)
{
$partName=New-Object System.Uri($file, [System.UriKind]"Relative")
$part=$ZipPackage.CreatePart($partName, "application/zip",
[System.IO.Packaging.CompressionOption]"Maximum")
$bytes=[System.IO.File]::ReadAllBytes($file)
$stream=$part.GetStream()
$stream.Write($bytes, 0, $bytes.Length)
$stream.Close()
}
$ZipPackage.Close()
Edit: Unreliable for larger files, maybe >10mb, YMMV. Something to do with appdomain evidence and isolated storage. The friendlier .NET 4.5 approach works nicely from PS v3, but wanted more memory in my case. To use .NET 4 from PS v2, config files need an unsupported tweak.
-
the major problem of ZipPackage is it is not normal *ZIP* file, but contains a content xml file. see: [how to avoid [Content_Types].xml in .net's ZipPackage class - Stack Overflow](https://stackoverflow.com/questions/3748970/how-to-avoid-content-types-xml-in-nets-zippackage-class) – aaron Apr 04 '18 at 04:10
-
@aaron One more great reason not to use this ever again! You've got stiff competition for "the major problem" here ;) – noam Apr 05 '18 at 17:05
Giving below another option. This will zip up a full folder and will write the archive to a given path with the given name.
Requires .NET 3 or above
Add-Type -assembly "system.io.compression.filesystem"
$source = 'Source path here'
$destination = "c:\output\dummy.zip"
If(Test-path $destination) {Remove-item $destination}
[io.compression.zipfile]::CreateFromDirectory($Source, $destination)

- 3,351
- 3
- 25
- 58

- 161
- 1
- 5
Here is a native solution for PowerShell v5, using the cmdlet Compress-Archive
Creating Zip files using PowerShell.
See also the Microsoft Docs for Compress-Archive.
Example 1:
Compress-Archive `
-LiteralPath C:\Reference\Draftdoc.docx, C:\Reference\Images\diagram2.vsd `
-CompressionLevel Optimal `
-DestinationPath C:\Archives\Draft.Zip
Example 2:
Compress-Archive `
-Path C:\Reference\* `
-CompressionLevel Fastest `
-DestinationPath C:\Archives\Draft
Example 3:
Write-Output $files | Compress-Archive -DestinationPath $outzipfile
Why does no one look at the documentation? The same .NET 4.5 library everyone is referencing lets you do anything you want, including creating an empty ZIP and adding individual files to it. In addition, the PowerShell Compress-Archive
cmdlet uses this library under the covers and is only a convenience function (it cannot delete files for instance).
See below for a code example:
# Load the .NET assembly
Add-Type -Assembly 'System.IO.Compression'
Add-Type -Assembly 'System.IO.Compression.FileSystem'
# Must be used for relative file locations with .NET functions instead of Set-Location:
[System.IO.Directory]::SetCurrentDirectory('.\Desktop')
# Create the zip file and open it:
$z = [System.IO.Compression.ZipFile]::Open('z.zip', [System.IO.Compression.ZipArchiveMode]::Create)
# Add a compressed file to the zip file:
[System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($z, 't.txt', 't.txt')
# Close the file
$z.Dispose()
Here's an overview on how to manipulate the zip archive while you're at it (just remember to close the file afterwards):
You can compress files by specifying a fourth parameter for
CreateEntryFromFile(...)
.Creating an entry returns a
ZipArchiveEntry
. This object lets you inspect the zipped file afterwards including letting you report the.CompressedLength
, view or change the.LastWriteTime
(needsUpdate
mode), and more below.If you need to inspect the ZIP archive later, you can access its
.Entries
property, and use the methods above as well as view the filename, the full path, the decompressed size, or delete the file (needsUpdate
mode).You can extract an archive two ways later. First open it, then extract either the entire archive or an individual entry (from
.Entries
or.GetEntry(...)
). You can also extract an archive by its filename alone.If you need to work with streams, you can create an empty entry and open its stream for writing afterwards. You can also modify an existing zip entry (from
.Entries
or.GetEntry(...)
), which would let you do everything in-memory.As a bonus, here is how to efficiently move all files in the zip file:
# Load the .NET assembly Add-Type -Assembly 'System.IO.Compression' Add-Type -Assembly 'System.IO.Compression.FileSystem' # Open the zip file $z = [System.IO.Compression.ZipFile]::Open('z.zip', [System.IO.Compression.ZipArchiveMode]::Update) # Only files have a name assigned, clone if deleting files ($z.Entries | Where-Object Name).FullName.Clone() | ForEach-Object { # Open streams $old, $new = ($z.GetEntry($_), $z.CreateEntry($_ + '.old')).Open() # Copy entry to new location and close streams $old.CopyTo($new) ($old, $new).Dispose() # Delete old entry if moving/renaming $z.GetEntry($_).Delete() } # Close the file $z.Dispose()
I encourage you to browse the documentation because that's how I found all this.

- 2,900
- 27
- 38
-
2Thank you for this, this is perfect. Especially compared to the Compress-Archive cmdlet which is badly designed and doesn't have a good way of specifying paths INSIDE the zip. – Rafael Kitover Feb 17 '20 at 01:18
What about System.IO.Packaging.ZipPackage
?
It would require .NET 3.0 or greater.
#Load some assemblys. (No line break!)
[System.Reflection.Assembly]::Load("WindowsBase, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
#Create a zip file named "MyZipFile.zip". (No line break!)
$ZipPackage=[System.IO.Packaging.ZipPackage]::Open("C:\MyZipFile.zip",
[System.IO.FileMode]"OpenOrCreate", [System.IO.FileAccess]"ReadWrite")
#The files I want to add to my archive:
$files = @("/Penguins.jpg", "/Lighthouse.jpg")
#For each file you want to add, we must extract the bytes
#and add them to a part of the zip file.
ForEach ($file In $files)
{
$partName=New-Object System.Uri($file, [System.UriKind]"Relative")
#Create each part. (No line break!)
$part=$ZipPackage.CreatePart($partName, "",
[System.IO.Packaging.CompressionOption]"Maximum")
$bytes=[System.IO.File]::ReadAllBytes($file)
$stream=$part.GetStream()
$stream.Write($bytes, 0, $bytes.Length)
$stream.Close()
}
#Close the package when we're done.
$ZipPackage.Close()
via Anders Hesselbom
For compression, I would use a library (7-Zip is good like Michal suggests).
If you install 7-Zip, the installed directory will contain 7z.exe
which is a console application.
You can invoke it directly and use any compression option you want.
If you wish to engage with the DLL, that should also be possible.
7-Zip is freeware and open source.
-
2Here is an example of using 7 zip with AES encryption from Powershell: http://codeblog.theg2.net/2010/02/powershell-7-zip-amazon-s3-upload.html – Greg Bray Feb 19 '10 at 23:22
This is really obscure but works. 7za.exe is standalone version of 7zip and is available with install package.
# get files to be send
$logFiles = Get-ChildItem C:\Logging\*.* -Include *.log | where {$_.Name -match $yesterday}
foreach ($logFile in $logFiles)
{
Write-Host ("Processing " + $logFile.FullName)
# compress file
& ./7za.exe a -mmt=off ($logFile.FullName + ".7z") $logFile.FullName
}

- 9,338
- 4
- 44
- 62
If someone needs to zip a single file (and not a folder): http://blogs.msdn.com/b/jerrydixon/archive/2014/08/08/zipping-a-single-file-with-powershell.aspx
[CmdletBinding()]
Param(
[Parameter(Mandatory=$True)]
[ValidateScript({Test-Path -Path $_ -PathType Leaf})]
[string]$sourceFile,
[Parameter(Mandatory=$True)]
[ValidateScript({-not(Test-Path -Path $_ -PathType Leaf)})]
[string]$destinationFile
)
<#
.SYNOPSIS
Creates a ZIP file that contains the specified innput file.
.EXAMPLE
FileZipper -sourceFile c:\test\inputfile.txt
-destinationFile c:\test\outputFile.zip
#>
function New-Zip
{
param([string]$zipfilename)
set-content $zipfilename
("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
(dir $zipfilename).IsReadOnly = $false
}
function Add-Zip
{
param([string]$zipfilename)
if(-not (test-path($zipfilename)))
{
set-content $zipfilename
("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
(dir $zipfilename).IsReadOnly = $false
}
$shellApplication = new-object -com shell.application
$zipPackage = $shellApplication.NameSpace($zipfilename)
foreach($file in $input)
{
$zipPackage.CopyHere($file.FullName)
Start-sleep -milliseconds 500
}
}
dir $sourceFile | Add-Zip $destinationFile

- 17,757
- 11
- 115
- 164
-
1This code relies on a shell application and then guesses 500ms to wait for it to finish... I'm not disagreeing that it works (in most cases). But it creates popups as you use it in every case where adding a compressed file takes some amount of time (easily reproduced with adding large files or working with large zips). Also if any zip operation is slower than whatever sleep time specified, it'll fail to add the file and leave behind a popup dialog box. This is terrible for scripting. I also downvoted the other answer that relies on a COM object because it doesn't address these pitfalls. – Pluto Oct 24 '18 at 23:41
Here is the working code, zipping all files from a source folder and create a zip file in destination folder.
$DestZip="C:\Destination\"
$Source = "C:\Source\"
$folder = Get-Item -Path $Source
$ZipTimestamp = Get-Date -format yyyyMMdd-HHmmss;
$ZipFileName = $DestZip + "Backup_" + $folder.name + "_" + $ZipTimestamp + ".zip"
$Source
set-content $ZipFileName ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
# Wait for the zip file to be created.
while (!(Test-Path -PathType leaf -Path $ZipFileName))
{
Start-Sleep -Milliseconds 20
}
$ZipFile = (new-object -com shell.application).NameSpace($ZipFileName)
Write-Output (">> Waiting Compression : " + $ZipFileName)
#BACKUP - COPY
$ZipFile.CopyHere($Source)
$ZipFileName
# ARCHIVE
Read-Host "Please Enter.."

- 177
- 1
- 4
function Zip-File
{
param (
[string]$ZipName,
[string]$SourceDirectory
)
Add-Type -Assembly System.IO.Compression.FileSystem
$Compress = [System.IO.Compression.CompressionLevel]::Optimal
[System.IO.Compression.ZipFile]::CreateFromDirectory($SourceDirectory,
$ZipName, $Compress, $false)
}
Note:
ZipName: Full Path of the Zip File which you want to create.
SourceDirectory: Full path to the directory containing the files which you would like to zip.

- 776
- 11
- 26
In case you have WinRAR installed:
function ZipUsingRar([String] $directory, [String] $zipFileName)
{
Write-Output "Performing operation ""Zip File"" on Target ""Item: $directory Destination:"
Write-Output ($zipFileName + """")
$pathToWinRar = "c:\Program Files\WinRAR\WinRar.exe";
[Array]$arguments = "a", "-afzip", "-df", "-ep1", "$zipFileName", "$directory";
& $pathToWinRar $arguments;
}
The meaning of the arguments: afzip creates zip archive, df deletes files, ep1 does not create full directory path within archive

- 3,172
- 30
- 26
-
I thought I finally found the answer to my problem when I saw this, but no matter what I do, WinRar won't run. If I use a batch file to run it, everything's fine, but if I try to run that batch file from a PowerShell script, nothing happens, it just goes on to the next part of the script which uploads the file to an FTP server. – s31064 Oct 26 '20 at 21:16
-
I tried using this function as is, and it does nothing. I don't get it. My $Arguments: `[Array]$arguments = 'a', '-ag-YYYY-MM-DD-NN', '-dh', '-ed', '-ep3', '-ilogE:\Logs\WinRar\backup.log', '-INUL', '-r', '-y', 'E:\UsageWebLogs\Weblogs', 'W:\', 'X:\', 'Y:\', 'Z:\';` – s31064 Oct 26 '20 at 21:25
Here is a slightly improved version of sonjz's answer,it adds an overwrite option.
function Zip-Files(
[Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$false)]
[string] $zipfilename,
[Parameter(Position=1, Mandatory=$true, ValueFromPipeline=$false)]
[string] $sourcedir,
[Parameter(Position=2, Mandatory=$false, ValueFromPipeline=$false)]
[bool] $overwrite)
{
Add-Type -Assembly System.IO.Compression.FileSystem
$compressionLevel = [System.IO.Compression.CompressionLevel]::Optimal
if ($overwrite -eq $true )
{
if (Test-Path $zipfilename)
{
Remove-Item $zipfilename
}
}
[System.IO.Compression.ZipFile]::CreateFromDirectory($sourcedir, $zipfilename, $compressionLevel, $false)
}

- 599
- 4
- 17
-
2Could you please elaborate more your answer adding a little more description about the solution you provide? – abarisone Apr 10 '15 at 08:41
-
I took a previous answer and improved it by adding overwrite option, not much more to say! – Lou O. Sep 26 '16 at 16:12
This should also work for compressing a single file without using a temp folder and using native .Net 4.5, converted from C# from this StackOverflow answer. It uses a nicer using syntax taken from here.
Usage:
ZipFiles -zipFilename output.zip -sourceFile input.sql -filename name.inside.zip.sql
Code:
function ZipFiles([string] $zipFilename, [string] $sourceFile, [string] $filename)
{
$fullSourceFile = (Get-Item -Path "$sourceFile" -Verbose).FullName
$fullZipFile = (Get-Item -Path "$zipFilename" -Verbose).FullName
Add-Type -AssemblyName System.IO
Add-Type -AssemblyName System.IO.Compression
Add-Type -AssemblyName System.IO.Compression.FileSystem
Using-Object ($fs = New-Object System.IO.FileStream($fullZipFile, [System.IO.FileMode]::Create)) {
Using-Object ($arch = New-Object System.IO.Compression.ZipArchive($fs, [System.IO.Compression.ZipArchiveMode]::Create)) {
[System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($arch, $fullSourceFile, $filename)
}
}
}
Using:
function Using-Object
{
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[AllowEmptyString()]
[AllowEmptyCollection()]
[AllowNull()]
[Object]
$InputObject,
[Parameter(Mandatory = $true)]
[scriptblock]
$ScriptBlock
)
try
{
. $ScriptBlock
}
finally
{
if ($null -ne $InputObject -and $InputObject -is [System.IDisposable])
{
$InputObject.Dispose()
}
}
}

- 1
- 1

- 180
- 3
- 9
-
Excellent. I was looking for a way to zip ONE file without using that `shell.application` business or 7-Zip / other separate utilities. I like the `Using-Object` function too, although I went for a shorter, quick-n-dirty approach without that. – Charlie Joynt May 04 '17 at 16:10
I use this snippet to check my database backups folder for backup files not compressed yet, compress them using 7-Zip, and finally deleting the *.bak
files to save some disk space.
Notice files are ordered by length (smallest to biggest) before compression to avoid some files not being compressed.
$bkdir = "E:\BackupsPWS"
$7Zip = 'C:\"Program Files"\7-Zip\7z.exe'
get-childitem -path $bkdir | Sort-Object length |
where
{
$_.extension -match ".(bak)" -and
-not (test-path ($_.fullname -replace "(bak)", "7z"))
} |
foreach
{
$zipfilename = ($_.fullname -replace "bak", "7z")
Invoke-Expression "$7Zip a $zipfilename $($_.FullName)"
}
get-childitem -path $bkdir |
where {
$_.extension -match ".(bak)" -and
(test-path ($_.fullname -replace "(bak)", "7z"))
} |
foreach { del $_.fullname }
Here you can check a PowerShell script to backup, compress and transfer those files over FTP.

- 4,117
- 2
- 33
- 70

- 2,705
- 23
- 28
Here a complete command line example to launch from cmd.exe or from ssh or what you want !
powershell.exe -nologo -noprofile -command "&{ Add-Type -A 'System.IO.Compression.FileSystem' [System.IO.Compression.ZipFile]::CreateFromDirectory('c:/path/to/source/folder/', 'c:/path/to/output/file.zip');}"
Regards

- 225
- 3
- 1
Loading the [System.IO.IOException]
class and using its methods is an important step in order to suppress unwanted errors, due the fact that it's a class not native to PowerShell, so expect various contexts of errors without it.
I error-controlled my script to the T, but got a lot of extra red 'file exists' output while using [System.IO.Compression.ZipFile]
class
function zipFiles(
[Parameter(Position=0, Mandatory=$true]
[string] $sourceFolder,
[Parameter(Position=1, Mandatory=$true]
[string]$zipFileName,
[Parameter(Position=2, Mandatory=$false]
[bool]$overwrite)
{
Add-Type -Assembly System.IO
Add-Type -Assembly System.IO.Compression.FileSystem
$compressionLevel = [System.IO.Compression.CompressionLevel]::Optimal
$directoryTest = (Test-Path $dailyBackupDestFolder)
$fileTest = (Test-Path $zipFileName)
if ( $directoryTest -eq $false)
{
New-Item -ItemType Directory -Force -Path $dailyBackupDestFolder
}
if ( $fileTest -eq $true)
{
if ($overwrite -eq $true ){Remove-Item $zipFileName}
}
try
{
[System.IO.Compression.ZipFile]::CreateFromDirectory($sourceFolder,$zipFileName,$compressionLevel)
}
catch [System.IO.IOException]
{
Write-Output ($dateTime + ' | ' + $_.Exception.Message ) | Out-File $logFile -append -force
}
}
What I am doing here is catching these IO Errors, such as accessing files that exist already, catching that error and directing it to a logfile that I am maintaining with a larger program.

- 110
- 5
Complete command-line Commands in Windows for Compressing and Extracting Directory is as follows:
For Compression:
powershell.exe -nologo -noprofile -command "& { Add-Type -A 'System.IO.Compression.FileSystem'; [IO.Compression.ZipFile]::CreateFromDirectory('C:\Indus','C:\Indus.zip'); }"
For Extracting:
powershell.exe -nologo -noprofile -command "& { Add-Type -A 'System.IO.Compression.FileSystem';[IO.Compression.ZipFile]::ExtractToDirectory('C:\Indus.zip','C:\Indus'); }"

- 12,708
- 2
- 36
- 40

- 693
- 9
- 18
Old thread but still, I got here :)
It is not an answer to the original question, but maybe someone will find it useful how to create ZipArchive object with PS.
# Example, if you have like I have a $myByteArray byte[] with the compressed data:
Add-Type -AssemblyName System.IO.Compression.FileSystem
# Fixed length stream:
$strm = New-Object -TypeName System.IO.MemoryStream -ArgumentList @(, $myByteArray);
# Create ZipArchive object
$arch = [System.IO.Compression.ZipArchive]::new($strm);
# List entries
$arch.Entries

- 24
- 2
-
There is already an accepted answer. This answer is not new, there are already multiple .NET answers based around System.IO.Compression.ZipFile. – Jeter-work May 13 '22 at 19:43