Solved

Make Copy-ToZip wait before executing next command

Posted on 2010-08-31
4
2,201 Views
Last Modified: 2013-04-25
I want to use the Powershell Pack Copy-ToZip module to zip some files.

I need to be able to zip each file individually, so file1.bak will be zipped to file1.zip, and delete file1.bak if successful.

What I'm running into is Copy-ToZip uses native windows api and executes asynchronously,  thus my script attempts to delete file1.bak before zipping is completed.

These are sql backups and are quite large, taking a long amount of time to zip.

I guess I can use some other method to zip, but I was attempting to use Posh 2.0 and Powershell Pack only if possible on all my hundreds of servers, rather than try to push out a zip exe or PSCX 2.0.

Here is the code i was writing to do this:
# Zip Files and e-mail when done

# This scripts zips each file in a folder individually, deleting the ext and appending zip as ext to existing filename.
# Use -Delete Switch to delete the file after zipping.

Param($SourceFolder, $DestinationFolder, $Filter, [switch] $Delete )

$Error.Clear()                          # Clear Error var coming into script

Import-Module FileSystem                # from Powershell Pack 2.0

$Filename = ""
if (!($SourceFolder)) { $SourceFolder = Read-Host "Enter SourcePath to be zipped" }
if (!($DestinationFolder)) {$DestinationFolder = Read-Host "Enter DestinationPath to be zipped to" }
if (!($Filter)) { $Filter = "*.*" }                     # If no filter passed for Get-ChildItem, set to all *.* 

$FilestoZip = Get-ChildItem $SourceFolder -Filter $Filter

ForEach ($File in $FilestoZip)
{
    if ( Test-Path "$DestinationFolder\$($File.baseName).zip" ) { Remove-Item "$DestinationFolder\$($File.baseName).zip" -Force }
    Write-Output = "Zipping $File to $DestinationFolder\$($File.baseName).zip"
    Copy-ToZip -File "$SourceFolder\$($File)" -ZipFile "$DestinationFolder\$($File.baseName).zip"
    Write-Output $Error[0]                              # Write last Error  (  i.e. Error[0]  )
    Remove-Item "$SourceFolder\$($File)" -force
}

Open in new window

0
Comment
Question by:MichaelOBrien
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
4 Comments
 
LVL 12
ID: 33570282
I'm assuming that Copy-To-Zip is a standard 3rd party windows executable and not a Windows Power Shell command.  If so then we can just change the command to one of the two following options to get the desired behavior:


CALL Copy-ToZip -File "$SourceFolder\$($File)" -ZipFile  "$DestinationFolder\$($File.baseName).zip"

START /I /C Copy-ToZip -File "$SourceFolder\$($File)" -ZipFile  "$DestinationFolder\$($File.baseName).zip"

I prefer CALL both should allow your script wait until the command completes.  Try both and use the one you prefer.  Attached I changed your code to use CALL.

# Zip Files and e-mail when done

# This scripts zips each file in a folder individually, deleting the ext and appending zip as ext to existing filename.
# Use -Delete Switch to delete the file after zipping.

Param($SourceFolder, $DestinationFolder, $Filter, [switch] $Delete )

$Error.Clear()                          # Clear Error var coming into script

Import-Module FileSystem                # from Powershell Pack 2.0

$Filename = ""
if (!($SourceFolder)) { $SourceFolder = Read-Host "Enter SourcePath to be zipped" }
if (!($DestinationFolder)) {$DestinationFolder = Read-Host "Enter DestinationPath to be zipped to" }
if (!($Filter)) { $Filter = "*.*" }                     # If no filter passed for Get-ChildItem, set to all *.* 

$FilestoZip = Get-ChildItem $SourceFolder -Filter $Filter

ForEach ($File in $FilestoZip)
{
    if ( Test-Path "$DestinationFolder\$($File.baseName).zip" ) { Remove-Item "$DestinationFolder\$($File.baseName).zip" -Force }
    Write-Output = "Zipping $File to $DestinationFolder\$($File.baseName).zip"
   CALL Copy-ToZip -File "$SourceFolder\$($File)" -ZipFile "$DestinationFolder\$($File.baseName).zip"
    Write-Output $Error[0]                              # Write last Error  (  i.e. Error[0]  )
    Remove-Item "$SourceFolder\$($File)" -force
}

Open in new window

0
 

Author Comment

by:MichaelOBrien
ID: 33570575
QCubed,

Thanks for the comment!  Copy-ToZip is a Powershell command.  It is added by the installing and using Import-Module PowerShellPack from within PowerShell

http://code.msdn.microsoft.com/PowerShellPack

I ran some code you suggested from within powershell, I get the error:

The term 'Call' is not recognized as the name of a cmdlet, function, script fil
e, or operable program. Check the spelling of the name, or if a path was includ
ed, verify that the path is correct and try again.

I'm thinking this is because CALL and START are cmd shell commands, and might need additional syntax to be run from within Powershell, could that be correct?  Although, since Copy-ToZip is a powershell command, it must be run from within Powershell I am thinking.

Thanks again for taking a look at this everyone!

Best Regards,

Michael
0
 
LVL 12

Accepted Solution

by:
Ben Personick (Previously QCubed) earned 500 total points
ID: 33571411
Yeah if you were using external utilities you would have already instatntiated a CMD session in yout PS script, since you are not calling a 3rd party utility (exe file) it makes no difference: the CALL and Start commands are Windows NT commands not PS commands.  Strange though I thought Power shell, just liek batch, normally waited for all native commands to complete before continuing on to the next one.

Also when I ran powershell I literally just called batch files from within it which auto-instantiated the CMD wrapper around them.

I did a little reasearch and foudn the following code change can be used with a Powershell internal command...  give it a spin.

# Zip Files and e-mail when done

# This scripts zips each file in a folder individually, deleting the ext and appending zip as ext to existing filename.
# Use -Delete Switch to delete the file after zipping.

Param($SourceFolder, $DestinationFolder, $Filter, [switch] $Delete )

$Error.Clear()                          # Clear Error var coming into script

Import-Module FileSystem                # from Powershell Pack 2.0

$Filename = ""
if (!($SourceFolder)) { $SourceFolder = Read-Host "Enter SourcePath to be zipped" }
if (!($DestinationFolder)) {$DestinationFolder = Read-Host "Enter DestinationPath to be zipped to" }
if (!($Filter)) { $Filter = "*.*" }                     # If no filter passed for Get-ChildItem, set to all *.* 

$FilestoZip = Get-ChildItem $SourceFolder -Filter $Filter

ForEach ($File in $FilestoZip)
{
    if ( Test-Path "$DestinationFolder\$($File.baseName).zip" ) { Remove-Item "$DestinationFolder\$($File.baseName).zip" -Force }
    Write-Output = "Zipping $File to $DestinationFolder\$($File.baseName).zip"
	$job = Start-Job { Copy-ToZip -File "$SourceFolder\$($File)" -ZipFile "$DestinationFolder\$($File.baseName).zip"}
	Wait-Job $job
	Receive-Job $job
    Write-Output $Error[0]                              # Write last Error  (  i.e. Error[0]  )
    Remove-Item "$SourceFolder\$($File)" -force
}

Open in new window

0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

This script can help you clean up your user profile database by comparing profiles to Active Directory users in a particular OU, and removing the profiles that don't match.
My attempt to use PowerShell and other great resources found online to simplify the deployment of Office 365 ProPlus client components to any workstation that needs it, regardless of existing Office components that may be needing attention.
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…

739 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