Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

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

share|improve this question

2 Answers 2

up vote 6 down vote accepted

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.

share|improve this answer
    
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 '12 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 '12 at 19:24
    
Agreed. That is neat. –  Ryan Ries Nov 14 '12 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 '12 at 19:34
    
$job = Start-Job { Do-Stuff } Wait-Job $job –  Ryan Ries Nov 14 '12 at 19:44

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.