ZIP Function - Need Additional Controls To Mitigate Occasional Looping

I have an extremely large volume of files that need to be individually ZIPed (in blocks of 200-400k files).  While using the function below, sometimes the file does not get added to the ZIP file (initialized/created as part of 'new-object') and the function gets stuck in an infinite loop checking for the pre-created ZIP file to grow in size greater than its initialized size of 24 bytes.  All files I'm compressing are less than 200-300k in size and compress immediately.  If the addition to the ZIP file takes longer than 50ms, I see an error pop up once and then it moves onto the next file because the second check for file growth becomes true and the file add has successfully completed.

Personally I just would like to add a counter that checks to see how many times the while statement gets executed so that after 5-10 times, it re-issues the the command to add the file to the zipfile (which appears to resolve the issue when executed manually from a seperate powershell window).

One option that came to mind was to wrap line for adding the file (into the ZIP file) into the while clause and then try to incorporate the counter in there.  I just haven't tried it yet.

Any additional thoughts on how to accomplish the above modification (to the script below) would be appreciated as my biggest issue is the inability to re-create the problem at-will.  

function zipit { 
  Param([string]$path) 

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

  if (-not (test-path $path)) { 
    set-content $path ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18)) 
  } 
  $ZipFile = (new-object -com shell.application).NameSpace($path) 
  $input | foreach {$zipfile.CopyHere($_.fullname); while ((Get-Item $path).length -le 25) {Start-Sleep -m 50}}

}

Any help is much appreciated.

- Rob

April 21st, 2015 2:37pm

Hi Rob,

I'd avoid using the shell in this manner, it doesn't really work well in a script. Use the .Net 4.5's ZipFile class instead:

https://msdn.microsoft.com/en-us/library/system.io.compression.zipfile%28v=vs.110%29.aspx

http://blogs.technet.com/b/heyscriptingguy/archive/2015/03/09/use-powershell-to-create-zip-archive-of-folder.aspx

Free Windows Admin Tool Kit Click here and download it now
April 21st, 2015 3:06pm

I would have loved to use that implementation except that I can't find examples that show how to zip up individual files as I only find folder examples like your second link.

FYI - I knew I'd get some grief on using 'CopyHere'.  I just have yet to find an implementation of the .NET 4.5 ZipFile class in Powershell the way I need to (one file at a time).

- Rob

April 21st, 2015 3:29pm

In that case try ZipFileExtensions instead:

https://msdn.microsoft.com/en-us/library/system.io.compression.zipfileextensions%28v=vs.110%29.aspx

Free Windows Admin Tool Kit Click here and download it now
April 21st, 2015 3:39pm

I think I started playing with this particular implementation but kept on running into issues with errors and not knowing why and was forced to go back to the 'CopyHere' method as I have a clock ticking for getting the work done.

Ironically I also just found the following article which uses it too:

https://danvers72.wordpress.com/2014/11/18/creating-a-zip-file-from-a-single-file/

Your input is greatly appreciated as it reaffirms that I was close previously and just wasn't having the time to do research properly.

- Rob

April 21st, 2015 3:54pm

Cheers, I hope the information helps down the line.

If you're in a time crunch, you can always just skip PowerShell and use the 7Zip standalone commandline utility:

http://www.7-zip.org/download.html

No installation required.

Another option might be to try using the Write-Zip function in the PSCX:

https://pscx.codeplex.com/

I haven't used these personally, but I've heard good things.

Free Windows Admin Tool Kit Click here and download it now
April 21st, 2015 3:58pm

Here are numerous articles on how to zip files with PowerShell: https://www.google.com/#newwindow=1&q=scripting+goys+zip+files

April 21st, 2015 6:02pm

Ironically I also just found the following article which uses it too:

https://danvers72.wordpress.com/2014/11/18/creating-a-zip-file-from-a-single-file/

Just to be clear, this function works perfectly:

Get-ChildItem C:\Scripting\Testing\4-21-2015\source -File -Recurse | ForEach {

    New-ArchiveFromFile -Source $_.FullName -Destination (Join-Path -Path $_.Directory -ChildPath "$($_.BaseName).zip")

}

The source files are left alone, but it would be easy enough to delete them if you wanted to.

Free Windows Admin Tool Kit Click here and download it now
April 21st, 2015 7:42pm

An interesting aside is that, if you use forms and events or, if you use event delegates in PS (Register-Event), yu can use the shell zip file creatoion method.  The biggest issue is that it runs  "async" to the current thread so it is hard to manage.

The dotNet classes are easiest and most reliable but still very primitive.

What we need ais a Net class that creates a transacted archive.  Either all files are  archived and deleted or the call is "rolled back".

April 21st, 2015 7:48pm

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics