Zipping Files with PowerShell

When I developed automssqlbackup, one of the key features was to optionally zip the generated database backup file.

I found solutions like this which essentially create an empty zip archive, then create a Shell.Application object to access this archive, and add files using the CopyHere or MoveHere methods of that object.

However, this approach has some severe drawbacks:

  • Zip file creation and access via Shell.Application can collide occasionally, so that the COM object cannot access the zip file
  • If such a collision occurs, the shell will display a message box which the user has to confirm/cancel, and the caller (the Powershell script, in this case) is not notified about the error situation
  • The MoveHere method does not seem to *move* in the sense that the original file is deleted after being added to the zip archive

(short rant: this is automation the Microsoft way. Provide a programming interface, and if things go wrong, display a message box. Provide functionality as asynchronous operation and not tell the caller when it’s finished. If this was *real* automation, the caller would receive an error notification and a success notification from the callee, and the caller would decide how to react)

Since these effects showed up soon after I tested my script on different machines, it was clear that zipping had to be solved more reliably: using SharpZipLib.

First SharpZipLib is loaded into the Powershell script:


I found there are 2 simple ways to create a zip archive and add a file to it:

Using ZipFile.Create() and *Update()

$zip = [ICSharpCode.SharpZipLib.Zip.ZipFile]::Create($zipname)

Quick and easy, but with a drawback: the filenames are stored including their original path information.

Using FastZip.CreateZip()

$zip = New-Object ICSharpCode.SharpZipLib.Zip.FastZip
$zip.CreateZip($zipname, $filenamedir, $false, "\.bak$")

$filenamedir is the base directory of all files to be included in the zip, followed by the recursive flag.

The final parameter is a bit tricky: it is named FileFilter, but it is not a DOS-like filter (“*.*”), but rather a regular expression being evaluated on each file. In the example above, all files with extension .bak are selected.

5 thoughts on “Zipping Files with PowerShell

  1. Pingback: Updating automssqlbackup « devioblog

  2. @stej: I used SharpZipLib before in another project (C#), it was easy to integrate, and it’s a plain .Net solution.

    Of course, using a command line zip tool is a valid option. As the Perl motto says: TMTOWTDI šŸ˜‰

  3. What if I want to tell the script to zip just the file older than 15 days? Right now, I have to move the files I want to zip into a folder, and then zip them.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.