Borrowing from Windows Explorer in PowerShell part 3: using extended properties with zip files

So a couple of posts back I showed a little bit of PowerShell which could create a new Zip file and hook into Windows Explorer’s object model to Add files to the Zip.

There always used to be a joke about backup products .. * Restore sold separately. So having showed the code to add files , I need something to copy files out of a zip.

 Function Copy-ZipContent  
{Param ($zipFile, $Path)

    if(test-path($zipFile)) {$shell = new-object -com Shell.Application

                             $destFolder = $shell.NameSpace($Path)

                             $destFolder.CopyHere(($shell.NameSpace($zipFile).Items()))}        
}

Of course now I want to see what is in the ZIP file. Since I’ve stuck to PowerShell Naming with Add-ZIPContent and Copy-ZipContent this function should probably be named Get-ZipContent. It uses the same processes as before – get a shell.NameSpace object to represent the ZIP file and then use its GetDetailsOf() method in the same way that getting folder properties did in the second part of this series. Where that gets 266 properties for a normal folder for a ZIP archive there are only 9. So the function I ended up with looks like this.

 Function Get-ZIPContent  
{Param ($zipFile=$(throw "You must specify a Zip File"), [Switch]$Raw)

 if (-not $ZipFile.EndsWith('.zip')) {$ZipFile += '.zip'} 

 if (test-path $Zipfile) {

        $shell = new-object -com Shell.Application

        $NS=$shell.NameSpace(((resolve-path $ZipFile).path))        
        $Files = $(foreach ($item in $NS.items() ) {0..8 | 
            foreach –begin {$ZipObj = New-Object -TypeName System.Object } `
                  -process {Add-Member -inputObject $ZipObj -MemberType NoteProperty 
                                       -Name ($NS.GetDetailsOf($null,$_)) -Value ($NS.GetDetailsOf($Item,$_)) }  `
                 -end     {$ZipObj} })   
        if ($raw) {$files} else {$files | format-Table -autosize}                                            
        }
} 

This function uses a trick I’ve used more and more lately. A loop which creates an object at the Begin stage, adds a property to it with each iteration and emits the object at the End Stage. In this case the loop is run once for each file and goes through the numbers 0..8 and adds a property getting the name for property with that number (that’s getdetailsOf with $null in place of the file) and the value of property (calling GetDetails of with the File). If the –RAW switch is specified it outputs the object so something else –normally I want something like this.

 Name                 Type                      Compressed size Password protected Method   Size    Ratio Date modified         CRC-32
----                 ----                      --------------- ------------------ ------   ----    ----- -------------         ------
hyperv.format.ps1xml PS1XML File               1.60 KB         No                 Deflated 23.0 KB ‎94%  ‎18/‎12/‎2008 ‏‎22:49 CC973E54
hyperv.ps1           Windows PowerShell Script 26.5 KB         No                 Deflated 122 KB  ‎79%  ‎19/‎12/‎2008 ‏‎00:07 D9877F44

It won’t take you very long looking at the code to see that I don’t recurse through directories stored in the zip file in the code above. I re-used some of the code I had for formatting something as a tree and put it into the final version which is in the attached file along with the other ZIP tools (which is subject to the terms of use that cover this site - see the link at the foot of the page).

ZIPtool.zip