Prof. Powershell
PowerShell File Frontier, Part 4: Zipped Files
Here's how to add files to a zipped file in PowerShell.
- By Jeffery Hicks
- 09/16/2014
More on this topic:
I hope you've been enjoying our exploration of file management techniques. Today, I want to start down a slightly different path. As with all of my Prof. PowerShell the journey is just as important as the destination so even though there are a number of practical options for what I'm going to cover, I hope you'll appreciate the techniques and concepts as much as the end result.
I am a big believer that when writing PowerShell expressions, to use cmdlets wherever possible instead of calling the .NET Framework directly. Personally I don't understand why someone would want to write
PS C:\> $now = [datetime]::now
Instead of
PS C:\> $now = Get-Date
But sometimes there are always exceptions, and certainly if there is no available cmdlet then by all means feel free to turn to the .NET Framework. That is exactly what we're going to do today. There are no out-of-the-box cmdlets for working with zipped files. Wouldn't it be nice to add files to a zip file using PowerShell? To do that requires classes from the System.IO.Compression.FileSystem namespace. All of this will require PowerShell v3 or later. The first step is to load the necessary framework bits into your PowerShell session.
PS C:\> Add-Type -assembly System.IO.Compression.FileSystem
Assuming you don't see any errors, you now have access to a number of .NET classes. I will be demonstrating how to use a number of static methods from these classes. But first, you might want to know what you can use:
PS C:\> [System.IO.Compression.ZipFile].GetMethods().name | Get-Unique
OpenRead
Open
CreateFromDirectory
ExtractToDirectory
ToString
Equals
GetHashCode
GetType
The last 4 methods are standard PowerShell methods so you can ignore them. We'll also be working with these classes as well:[System.IO.Compression.ZipArchive], [System.IO.Compression.ZipFileExtensions] and [System.IO.Compression.ZipArchiveEntry]. These classes also will have properties we can use:
PS C:\> [System.IO.Compression.ZipArchive].GetProperties().name
Entries
Mode
PS C:\> [System.IO.Compression.ZipArchiveEntry].GetProperties().Name
Archive
CompressedLength
FullName
LastWriteTime
Length
Name
If you use the PowerShell ISE or other scripting editor with Intellisense you can easily discover these classes as you can see in Figure 1.
To work with classes you need to create an object. Sometimes you can simply use New-Object, but if you get an error like Figure 2, you'll need to figure out the constructor.
Here's one way you can figure out how to create a constructor:
[System.IO.Compression.ZipArchive].GetConstructors() |
foreach {
$params = $_.GetParameters()
$out= for ($i=0; $i -lt $params.count;$i++) {
"<$($params[$i].ParameterType)> $($params[$i].name)"
}
$out -join ","
}
In the console I get a result like this:
<System.IO.Stream> stream
<System.IO.Stream> stream,<System.IO.Compression.ZipArchiveMode> mode
<System.IO.Stream> stream,<System.IO.Compression.ZipArchiveMode> mode,<bool> leaveOpen
<System.IO.Stream> stream,<System.IO.Compression.ZipArchiveMode> mode,<bool> leaveOpen,<System.Text.Encoding> entryNameEncoding
Or you could always read the MSDN documentation. But I think I've probably left your head spinning as it is so we'll wrap up today's tutorial and resume next time with some practical applications.
About the Author
Jeffery Hicks is an IT veteran with over 25 years of experience, much of it spent as an IT infrastructure consultant specializing in Microsoft server technologies with an emphasis in automation and efficiency. He is a multi-year recipient of the Microsoft MVP Award in Windows PowerShell. He works today as an independent author, trainer and consultant. Jeff has written for numerous online sites and print publications, is a contributing editor at Petri.com, and a frequent speaker at technology conferences and user groups.