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 Responses to Zipping Files with PowerShell

  1. […] changing the zip functionality to SharpZipLib I modified the mail notifications to include the backup schedule (daily, weekly, monthly) in the […]

  2. stej says:

    Why did you decided to not to use command line call e.g. c:\prgs\7zip\7z.exe a c:\ c:\temp\tozip\*.xml

  3. devio says:

    @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 šŸ˜‰

  4. stej says:

    Sure, np šŸ™‚ I was just curious, because the commmand line zip is much faster for me.

    Fyi: I have found a post that compares zipping in .net: It is in czech, but you can see other zipping tools at least (in the table).

  5. Smalls says:

    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 )

Google+ photo

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

Twitter picture

You are commenting using your Twitter 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.

%d bloggers like this: