force PowerShell to wait for cmdlet execution to end

Posted on 2009-05-01
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

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\] and [g:\test\].

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
    LVL 70

    Expert Comment

    by:Chris Dent

    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

    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!
    LVL 4

    Accepted Solution

    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.

    Author Comment

    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 70

    Assisted Solution

    by:Chris Dent


    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

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

    Featured Post

    Highfive Gives IT Their Time Back

    Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

    Join & Write a Comment

    Hi all.   The other day I had to change the passwords for a bunch of users on the fly. Because they were so many, I decided to do it in an automated way and I would like to share it with you all.   If you are not doing it directly in a Domain Co…
    In this previous article (, we made basic license assignments to users in O365. When I say basic, the method is the simplest way …
    The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…
    This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

    728 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

    Need Help in Real-Time?

    Connect with top rated Experts

    19 Experts available now in Live!

    Get 1:1 Help Now