force PowerShell to wait for cmdlet execution to end

Posted on 2009-05-01
Medium Priority
Last Modified: 2012-05-06
Before I forget, credit where credit is due for as far as I've gotten: the following code is adapted from http://mow001.blogspot.com/2006/01/msh-out-zip-function.html.

Okay, here's my challenge: I would like to create a function that will accept a series of filenames (full paths) as arguments, and zip them ONE AT A TIME to the same folder and filename, but with ".zip" appended.

So [PS> zipfiles "g:\test\file1.txt" "g:\test\file2.txt"] will generate [g:\test\file1.txt.zip] and [g:\test\file2.txt.zip].

Here's something that works:

function zipFiles {
  for( $i = 0; $i -lt $args.length; $i++ ){
    # Define the source and destination file paths.
    $FileName = $args[$i]
    $ZipName = $FileName + ".zip"
    # Create code to zip the file.
    $cmds = ' $' + "ZipFile = (new-object -com shell.application).NameSpace('$ZipName');"
    $cmds += ' $' + "ZipFile.CopyHere('$FileName');"

    # Execute the code in a separate process and wait for it to exit, so we won't overload the machine.
    write-host "Zipping '$FileName...'"
    set-content $ZipName("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
    [diagnostics.process]::start("powershell", "-noexit -command & {$cmds}").waitforexit()
    write-host "...done."

...BUT the "-noexit" is highly undesirable, since there are a lot of files to be zipped and I would like to be able to start it and walk away, rather than sit there and close the secondary window for each file.

The problem is, if I remove the "-noexit" it doesn't work.  The secondary window doesn't wait for CopyHere() to finish; it just opens and closes in a flash without doing anything.

The ideal solution would be something that tells PowerShell to wait for a given cmdlet to finish executing before going on to the next such that the secondary window wouldn't even be necessary.

Hopefully the solution is obvious to the Shellistas here, but I'm new and confused.
Question by:Bitley
  • 3
  • 2
LVL 71

Expert Comment

by:Chris Dent
ID: 24282758

If it's doing it one at a time why not just do each inline rather than spawning a separate PowerShell process? What does the separate process give you here?


Author Comment

ID: 24283143
Thanks Chris, good question - quite possibly the separate process is giving me nothing.

All I'm trying to accomplish is to single-thread (I believe that's the right term here) the execution so that one file at a time is compressed.  Without the separate process and the .waitforexit, as many zip processes as there were files would be spawned simultaneously, doing Bad Things to the machine since some of the files are multi-GB.

In case there's any question about it, the important part is the end result: zipping multiple files one at a time.  Feel free to ignore the code listing - if there's a completely different and better way to accomplish the goal, I'm all ears!

Accepted Solution

peter_field earned 1600 total points
ID: 24288238
The code is using the shell.application COM object, which simply invokes the shell to perform the action for you, it runs asynchronously and doesn't have an option to run synchronously, so you're out of luck. It will also pop any errors up on screen. I am disappointed at windows lack of decent support for ZIP, I haven't found any way to zip files progmatically reliably (i.e. you can wait and get an exit code or whatever to determine success).

I'd suggest obtaining a 3rd party app that supports being invoked from the command line (like 7zip or winzip) and calling them to do the zipping for it, it will be more reliable.
 The Evil-ution of Network Security Threats

What are the hacks that forever changed the security industry? To answer that question, we created an exciting new eBook that takes you on a trip through hacking history. It explores the top hacks from the 80s to 2010s, why they mattered, and how the security industry responded.


Author Comment

ID: 24294827
Thanks Peter, even though that was the kind of answer I was afraid of!
I'll leave this thread here for another day or two to see if there are more comments.
Anybody else?  Anybody?
LVL 71

Assisted Solution

by:Chris Dent
Chris Dent earned 400 total points
ID: 24302606


Sorry for the late response.

I've found the same problems as Peter with this. It's no fun trying to get it to run in a controlled manner. And lack of proper support for things like this is extremely frustrating.

There are quite a few threads on using 7Zip instead, obviously with greater success since you're executing on the command line.


Author Closing Comment

ID: 31577031
Thanks guys, even though the answer wasn't what I was hoping for!  Have a great weekend.

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A project that enables an administrator to perform actions within a user session context not just at the time of login but any time later on day(s) or week(s) later.
Previously, on our Nano Server Deployment series, we've created a new nano server image and deployed it on a physical server in part 2. Now we will go through configuration.
The viewer will learn how to dynamically set the form action using jQuery.
Screencast - Getting to Know the Pipeline
Suggested Courses
Course of the Month17 days, 12 hours left to enroll

829 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question