Solved

Make Copy-ToZip wait before executing next command

Posted on 2010-08-31
4
2,187 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
  • 2
4 Comments
 
LVL 11

Expert Comment

by:Ben Personick
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 11

Accepted Solution

by:
Ben Personick 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

Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

Question has a verified solution.

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

Synchronize a new Active Directory domain with an existing Office 365 tenant
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 a recent question (https://www.experts-exchange.com/questions/28997919/Pagination-in-Adobe-Acrobat.html) here at Experts Exchange, a member asked how to add page numbers to a PDF file using Adobe Acrobat XI Pro. This short video Micro Tutorial sh…
Established in 1997, Technology Architects has become one of the most reputable technology solutions companies in the country. TA have been providing businesses with cost effective state-of-the-art solutions and unparalleled service that is designed…

803 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