A PowerShell wrapper for 7-Zip

For many years now, my favorite compression utility is 7-Zip. It's free, open source, fast, convenient, available on almost any platform - what more could you wish for?

I've also started using 7-Zip as my program of choice for all kinds of backups, so I need to run it from batch files and Powershell scripts. Fortunately, there's a command line version of 7-Zip that doesn't need to be installed: 7za.exe (the a stands for stand-Alone). You can copy it onto any Windows PC and it'll just work. It's not too hard to use, but I like having Powershell's argument checking and help system, so I can type:

New-7ZArchive -Path archive -Type 7z -Include *.jpg,*.png -Recurse

So I made a Powershell module that wraps the functionality of 7-Zip (or, to be more precise: 7za.exe). It contains the following cmdlets:

  • New-7zArchive - for creating new archives
  • Add-7zArchive - to add files to an existing archive
  • Update-7zArchive - to update files in an existing archive
  • Get-7zArchive - to get a list of all files in the archive
  • Test-7zArchive - to check the integrity of an existing archive
  • Expand-7zArchive - to extract files from an existing archive
  • New-7zSfx - for creating self-extracting archives

New-7zArchive, Add-7zArchive, Update-7zArchive and Test-7zArchive are more or less self-explanatory. They adhere to the general Powershell naming conventions for their arguments:

  • Path: the path of the archive
  • Include: a list of files or patterns to include in the operation
  • Exclude: a list of files or patterns to exclude from the operation
  • Recurse: work on Include-d files recursively
  • Type: the type of the archive to create, 7z (default) or zip.

Get-7zArchive produces a list of Powershell objects with properties Name (string), Length (int), Compressed (int), and Mode (string). To get the number of files in an archive, use

(Get-7zArchive somearchive.7z).Count

Of course, every command is self-documenting (don't you just love that about Powershell>) so you can always type

help New-7zSfx

Creating self-extracting archives

My personal favorite is New-7zSfx. This cmdlet creates a self-extracting archive, i.e. an executable file that will extract its contents to some temporary directory, run a command of your choosing (like "setup") and clean up after itself. Great for distributing MSI installation packages, or single-use tools that require no installation.

This operation is not as straightforward as the others. First, a 7-Zip archive is made (always of type 7z, not zip) that contains the necessary files. Then, a configuration file is created that contains the parameters for the extraction and the command to execute after that. This configuration files is then combined with 7zsd.sfx (a special file that contains the extraction logic), and the newly created archive itself to form the actual executable.

Here's where the power of Powershell really shines. The New-7zSfx command has lots of optional arguments, allowing you to customize procedure, and it takes care of all the magic. Type:

New-7zSfx MyToolInst -Include MyTool.exe,MyTool.exe.config -CommandToRun MyTool

to create an executable called MyToolInst.exe that extracts MyTool.exe and its configuration file to an (unkown) temporary directory and starts MyTool.exe from there.

If you'd like the user to approve first, use the -BeginPrompt argument. This will display a small dialog (with a configurable text) asking the user if extraction should go ahead.

New-7zArchive

NAME
New-7zArchive

SYNOPSIS
Create a new 7-Zip archive

SYNTAX
New-7zArchive [-Path] <String> [-Include] <String[]> [-Exclude <String[]>] [-Type <String>] [-Recurse] [-Switches <String>] [<CommonParameters>]

DESCRIPTION
Use this cmdlet to create 7-Zip archives. Possible types are 7z (default) and zip.
The archive file is overwritten if it exists!

PARAMETERS
-Path <String>
The path of the archive to create

-Include <String[]>
A list of file names or patterns to include

-Exclude <String[]>
A list of file names or patterns to exclude

-Type <String>
The type of archive to create

-Recurse [<SwitchParameter>]
Apply include patterns recursively

-Switches <String>
Additional switches for 7za

Add-7zArchive

NAME
Add-7zArchive

SYNOPSIS
Add files to a 7-Zip archive

SYNTAX
Add-7zArchive [-Path] <String> [-Include] <String[]> [-Exclude <String[]>] [-Recurse] [-Switches <String>] [<CommonParameters>]

DESCRIPTION
Use this cmdlet to add files to an existing 7-Zip archive. If the archive does not
exists, it is created

PARAMETERS
-Path <String>
The path of the archive to add to

-Include <String[]>
A list of file names or patterns to include

-Exclude <String[]>
A list of file names or patterns to exclude

-Recurse [<SwitchParameter>]
The type of archive to create
Apply include patterns recursively

-Switches <String>
Additional switches for 7za

The script

Here's the actual source of the module. Place it anywhere, call it 7-Zip.psm1 and import it into your scripts:

Import-Module [path-to-module]\7-Zip.psm1

Make sure you download 7-Zip from 7-Zip.org. Extract 7za.exe (from the main download) and 7zsd.sfx (from the Extras download) and place them in the same directory as the powershell module 7-Zip.psm1. The module won't work without them!

The source code is in this Gist: