Custom Archiving in PowerShell 5.0

Posted on February 18, 2016 by Jeff Hicks in PowerShell with 0 Comments

Tutorial Hero

In a previous article I demonstrated how to use the new Compress-Archive cmdlet in PowerShell 5.0. In that article, I needed to create a zip file of selected files and retain the folder structure. In my original command I wanted to zip up XML files that reside in a number of subfolders under C:\Work. How can I retain that information?

I couldn’t find a simple way by using the cmdlet’s parameters or basic pipeline expressions. I have a solution, but it takes a little more effort.

Because I know the only way to maintain the folder structure is to only specify a folder name if I copy the files to a new directory structure and zip that up, then I should end up with a structured archive. Here’s how I accomplished this using the same XML files.

First, I’m going to get all the files I want and group them by their directory name. I’m sorting the results on the directory name so that when I create the corresponding temp folders, parent folders will get created first, although in reality, PowerShell doesn’t really care.

The rest of the code looks like this:

I’m using ForEach-Object in a way you may not be familiar with. I’m piping each group object to ForEach, but before I process anything, I delete my target zip file if it already exists and create a random folder name in the TEMP directory.

Then for each group object I split apart the name, which is the directory name, getting everything after C: because my top-level folder is C:\Work.

Sponsored

If it was something nested I’d need a bit more code to get just the top-level part, probably something with regular expressions. Once I have the folder path, I can create a new version of it in the randomly generated temp folder.

Once this is in place, I can copy the files from each group to the corresponding temp folder.

The end result is the same directory structure for all of the XML files.

Once all of the files are copied, in the End scriptblock, I can create the archive getting the top folder in the temp directory, in this case Work. My solution assumes you will only have a single folder in the root of the temporary directory.

When the zip file is finished I delete the temporary folder and files.

An archive with folders (Image Credit: Jeff Hicks)

An archive with folders (Image Credit: Jeff Hicks)

My zip file now has just the XML files I was after and their corresponding folders. You could take my code and turn it into a wrapper function or perhaps even create a proxy version of Compress-Archive. If you get around to doing this I hope you’ll let me know. Otherwise I’ll put it on my ever-growing to-do list

Before we leave our exploration of the archive cmdlets we need to talk about unzipping. Expanding an archive is trivial using Expand-Archive. All you need to do is specify the zip file and destination directory.

Be aware that the target folder must already exist or you will get an error. Likewise, If the same file exists in the target PowerShell will throw an exception. You can solve that by using –Force.

Expanding will also recreate any folders.

Viewing expanded folders (Image Credit: Jeff Hicks)

Viewing expanded folders (Image Credit: Jeff Hicks)

Sponsored

As I mentioned the cmdlets are pretty basic, but they get the job done. Are they something you might use, and what kind of IT management problem do they solve? What else do you wish they would do? Feel free to leave your thoughts in the comments.

Sponsored

Tagged with ,