Solved

Make Copy-ToZip wait before executing next command

Posted on 2010-08-31
4
2,195 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

Has Powershell sent you back into the Stone Age?

If managing Active Directory using Windows Powershell® is making you feel like you stepped back in time, you are not alone.  For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why.

Question has a verified solution.

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

Create and license users in Office 365 in bulk based on a CSV file. A step-by-step guide with PowerShell script examples.
A quick Powershell script I wrote to find old program installations and check versions of a specific file across the network.
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…

821 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