Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Make Copy-ToZip wait before executing next command

Posted on 2010-08-31
4
Medium Priority
?
2,222 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 14
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 14

Accepted Solution

by:
Ben Personick (Previously QCubed) earned 2000 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

Q2 2017 - Latest Malware & Internet Attacks

WatchGuard’s Threat Lab is a group of dedicated threat researchers committed to helping you stay ahead of the bad guys by providing in-depth analysis of the top security threats to your network.  Check out our latest Quarterly Internet Security Report!

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.
In the absence of a fully-fledged GPO Management product like AGPM, the script in this article will provide you with a simple way to watch the domain (or a select OU) for GPOs changes and automatically take backups when policies are added, removed o…
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…
This tutorial will teach you the special effect of super speed similar to the fictional character Wally West aka "The Flash" After Shake : http://www.videocopilot.net/presets/after_shake/ All lightning effects with instructions : http://www.mediaf…

609 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