PowerShell 5.0 Tutorial: Working with Zip Files

powershell-hero-img
In continuing my exploration of what’s new in PowerShell 5.0, I think you’ll like the new cmdlets designed to work with ZIP files. PowerShell now includes a few basic cmdlets for creating and expanding archives. They probably aren’t as full featured as other compression utilities like WinRAR, but they are easy to use. Let’s take a look.

The cmdlets are part of the Microsoft.PowerShell.Archive module.

The new archive cmdlets (Image Credit: Jeff Hicks)
The new archive cmdlets (Image Credit: Jeff Hicks)

The Compress-Archive cmdlet is pretty straightforward. Specify some files to be compressed and set a destination.

dir c:\work\*.xml -Recurse | Compress-Archive -DestinationPath C:\work\XMLData.zip

If the zip file already exists, then you will get an error. So if you want to create something totally new, you need to test for the archive first and delete it. Otherwise, you can use the Update parameter, which is self explanatory.

dir c:\work\*.xml -Recurse | Compress-Archive -DestinationPath C:\work\XMLData.zip -update

You’ll end up with a zip file like this:

The new zip file (Image Credit: Jeff Hicks)
The new zip file (Image Credit: Jeff Hicks)

Notice that no directory information is stored. More on that in a moment.
Compress-Archive includes a parameter to specify the compression level. The default is Optimal, which will take the most time, but create the smallest archive possible. You can also specify NoCompression, which simply stores the files or FastestUse. This is a speedy option with some degree of compression.
To give you a comparison, the XML files I just zipped take up about 201 MB on disk. I’ll create separate zips with each compression level.

dir c:\work\*.xml -Recurse | Compress-Archive -DestinationPath C:\work\XMLData-Optimal.zip
dir c:\work\*.xml -Recurse | Compress-Archive -DestinationPath C:\work\XMLData-Fastest.zip -CompressionLevel Fastest
dir c:\work\*.xml -Recurse | Compress-Archive -DestinationPath C:\work\XMLData-None.zip -CompressionLevel NoCompression

Of course, your compression rates will vary depending on the file types. But here’s what I end up with.

Comparing rates (Image Credit: Jeff Hicks)
Comparing rates (Image Credit: Jeff Hicks)

Here’s what WinRAR reports for each:
Optimal statistics (Image Credit: Jeff Hicks)
Optimal statistics (Image Credit: Jeff Hicks)

Fastest statistics (Image Credit: Jeff Hicks)
Fastest statistics (Image Credit: Jeff Hicks)

F
No compression statistics (Image Credit: Jeff Hicks)
No compression statistics (Image Credit: Jeff Hicks)

If you want to create an archive that retains the folder structure, you need to specify a folder.

Compress-Archive -Path c:\work -DestinationPath d:\temp\work.zip -CompressionLevel Fastest -Update

You can see the folder structure in the zip file

An archive with folder structure (Image Credit: Jeff Hicks)
An archive with folder structure (Image Credit: Jeff Hicks)

I’m sure you can find plenty of compression utilities and even PowerShell scripts, but it is nice to finally have a set of cmdlets out of the box to get the job done. Granted, Compress-Archive doesn’t come with a lot of bells and whistles, but I think its simplicity as an asset, especially for those of you still getting your feet wet with PowerShell.
Before I go, let me come back to a drawback that personally I find a bit frustrating. What if you want to create a zip file of selected files and retain the folder structure? For example, in my original command the XML files are in a number of subfolders under C:\Work. How can I retain that information? I want an archive of all the XML files but also their folder paths. That way I could expand the zip file and recreate the data structure. I know I could use some of the .NET compression classes directly but that’s a bit complicated and cmdlets are generally preferred. Fortunately after a little experimentation, I think I’ve hit upon a solution, which I’ll explain and share in another article. Oh, and I’ll also cover how to extract files.

As always, comments are welcome and encouraged. Is this something you would use?