2

I have written a PowerShell script that zips the contents of a folder and sends it to a server for backup. The issue is that the copy process doesn't wait for the zip process to finish. I have tried using Out-Null and Wait-Process, and nothing seems to be working. Out-Null just doesn't do anything, and Wait-Process tells me that no such process exists. I can't seem to figure out the process name for the Windows Compression. Any help would be greatly appreciated. Below is the part of the code I would like to have paused until it finishes.

function out-zip { 
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)} 
} 
gi "C:\File-Backups\Share1" | out-zip C:\File-Backups\transfer\PC1-Backup 

enter image description here

1
  • could you share your code - I have the exact same problem but using start job, my files aren't being compressed. Nov 19, 2014 at 14:48

2 Answers 2

6

Are you sure that code actually compresses files into a valid zip format? It doesn't look like it does anything useful to me. (edit: Oh it does? Neat!)

Anyway, to answer your question regardless, Out-Null doesn't do anything because it's Out-Null... and Wait-Process doesn't do anything because you are not running a process.

What you want are Powershell Jobs.

Start-Job

http://technet.microsoft.com/en-us/library/hh849698.aspx

Wait-Job

http://technet.microsoft.com/en-us/library/hh849735.aspx

edit 2: Also, it looks like you're using Powershell v3!

[Reflection.Assembly]::LoadWithPartialName( "System.IO.Compression.FileSystem" )
$src_folder = "D:\stuff"
$destfile = "D:\stuff.zip"
$compressionLevel = [System.IO.Compression.CompressionLevel]::Optimal
$includebasedir = $false
[System.IO.Compression.ZipFile]::CreateFromDirectory($src_folder,$destfile,$compressionLevel, $includebasedir )

Put a foreach around the last line in there as appropriate to zip each one of your files, or however you want to do it, then wrap the whole thing as the input to a Start-Job.

9
  • I just edited post with a picture of the folder being compressed and the created file. It seems to do everything that it's suppose to do. I will take a look at the Powershell Jobs. Thanks
    – Patrick
    Nov 14, 2012 at 19:16
  • @Ryan The ComObject Shell.Application (Windows Shell) handles .zip files natively (i.e. you can unzip from Explorer.exe, or drag files into an existing .Zip). What really stands out here is that the OP is actually craving the zipfile type, by-hand, into the start of file (PK[ETX][EOT]...) -- neat.
    – jscott
    Nov 14, 2012 at 19:24
  • Agreed. That is neat.
    – Ryan Ries
    Nov 14, 2012 at 19:26
  • @jscott I just started learning how to make PowerShell scripts today, and I really don't understand the second part of your post. Am I going the wrong way about this?
    – Patrick
    Nov 14, 2012 at 19:34
  • $job = Start-Job { Do-Stuff } Wait-Job $job
    – Ryan Ries
    Nov 14, 2012 at 19:44
3

The process doing the compressing is Explorer, the Windows shell (so, you can't wait for the process to quit because it always runs).

Here's a blog post with some code extending your example, and using file-lock tests to determine when the compression is finished:

http://www.technologytoolbox.com/blog/jjameson/archive/2012/02/28/zip-a-folder-using-powershell.aspx

Otherwise, you're looking at using some external zip library for PowerShell which doesn't use explorer, or calling out to a program like 7-Zip command line client to do the work and waiting for that to finish.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .