Prof. Powershell
PowerShell File Frontier, Part 5: Analyzing Compressed Flies
Prof. PowerShell delves deeper into what can be done with zipped files.
- By Jeffery Hicks
- 09/23/2014
More on this topic:
Let's pick up where we left off using the compression classes from the .NET Framework. If you don't know what I'm talking about, take a few minutes to read the previous article. Let's start our exploration with looking inside a zip file. The [System.IO.Compression.ZipFile] class is what we'll need to use. This class doesn't appear to have any constructors so we'll need to use the classes static methods.
PS C:\> [System.IO.Compression.ZipFile].GetMethods().Name | select -unique
OpenRead
Open
CreateFromDirectory
ExtractToDirectory
ToString
Equals
GetHashCode
GetType
To invoke a static method you use the :: operator. But you might not know how to use the method so ask:
PS C:\> [System.IO.Compression.ZipFile]::OpenRead.OverloadDefinitions
static System.IO.Compression.ZipArchive OpenRead(string archiveFileName)
Some methods may have several parameter options, which is what you see with the OverloadDefinitions property. In this case, to open a zip file, presumably in read-only mode, it seems all we need to do is specify the path to the file. Let's try.
PS C:\> $zip = [System.IO.Compression.ZipFile]::OpenRead("c:\zip\demo.zip")
No errors so what is $zip?
PS C:\> $zip
Entries Mode
------- ----
{chi-hvr2-health-full.htm, chi-hvr2-health.htm, EventLo... Rea
Looks like the Entries property is a collection of files in the zip archive.
PS C:\> $zip.entries | Out-GridView
I piped the results to Out-Gridview to make it easier to view.
If you pipe the Entries to Get-Member you'll see that these are System.IO.Compression.ZipArchiveEntry objects. By the way, if you pipe $zip to Get-Member you'll see that object is a System.IO.Compression.ZipArchive.
The objects are no different than any other object in PowerShell so you can tweak the output anyway you need.
$zip.entries | Select Fullname,LastWritetime,
@{Name="Size";Expression={$_.length}},
@{Name="CompressedSize";Expression={$_.Compressedlength}},
@{Name="PctZip";Expression={[math]::Round(($_.compressedlength/$_.length)*100,2)}} |
Sort Size -Descending | format-table –AutoSize
All I've done here is to rename a few properties to make them a little more admin friendly as well as add a custom property showing the compression percentage for each file. My results are shown in Figure 2.
The last step, which is important, is that you need to close the zip file. If you look back at the methods for the zip file you won't see anything to close the file. But remember, $zip is a different type of object. This is where Get-Member comes in handy.
PS C:\> $zip | Get-Member -MemberType methods
TypeName: System.IO.Compression.ZipArchive
Name MemberType Definition
---- ---------- ----------
CreateEntry Method System.IO.Compression.ZipArchiveEntry CreateEntry(string
entryName), System.IO.Compression....
Dispose Method void Dispose(), void IDisposable.Dispose()
Equals Method bool Equals(System.Object obj)
GetEntry Method System.IO.Compression.ZipArchiveEntry GetEntry(string
entryName)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
It still may not be clear to you, so let me tell you that Dispose() is what you are after.
PS C:\> $zip.Dispose()
Now the file is closed and ready to be used. Next time we'll look at creating a zip file and adding some files.
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.