10
3
In a PowerShell script, I want to zip a folder before deleting the folder. I run the following (I don't remember where I found the snippet):
function Compress-ToZip
{
param([string]$zipfilename)
if(-not (test-path($zipfilename)))
{
set-content $zipfilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
(Get-ChildItem $zipfilename).IsReadOnly = $false
}
$shellApplication = new-object -com shell.application
$zipPackage = $shellApplication.NameSpace($zipfilename)
foreach($file in $input)
{
$zipPackage.CopyHere($file.FullName)
}
}
This snippet actually compress the folder, but in an asynchronous way. In fact, the CopyHere method of the Shell.Application objects starts the compression and does not wait for its completion. The next statements of my scripts then mess up (as the zip file process is not completed).
Any suggestions? If possible I'd like to avoid adding any executable files and stay on pure Windows features.
[edit] full content of my PS1 file minus the actual name of the DB. The goal of the script is to backup a set of SQL db, then zip the backups in a single package in a folder named with the current date:
$VerbosePreferenceBak = $VerbosePreference
$VerbosePreference = "Continue"
add-PSSnapin SqlServerCmdletSnapin100
function BackupDB([string] $dbName, [string] $outDir)
{
Write-Host "Backup de la base : $dbName"
$script = "BACKUP DATABASE $dbName TO DISK = '$outDir\$dbName.bak' WITH FORMAT, COPY_ONLY;"
Invoke-Sqlcmd -Query "$script" -ServerInstance "." -QueryTimeOut 600
Write-Host "Ok !"
}
function Compress-ToZip
{
param([string]$zipfilename)
Write-Host "Compression du dossier"
if(-not (test-path($zipfilename)))
{
set-content $zipfilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
(Get-ChildItem $zipfilename).IsReadOnly = $false
}
$shellApplication = new-object -com shell.application
$zipPackage = $shellApplication.NameSpace($zipfilename)
foreach($file in $input)
{
$zipPackage.CopyHere($file.FullName)
}
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
}
$targetDir = "E:\Backup SQL"
$date = Get-Date -format "yyyy-MM-dd"
$newDir = New-Item -ItemType Directory "$targetDir\$date\sql" -Force
BackupDB "database 1" "$newDir"
BackupDB "database 2" "$newDir"
BackupDB "database 3" "$newDir"
Get-Item $newDir | Compress-ToZip "$targetDir\$date\sql_$date.zip"
Write-Host "."
remove-item $newDir -Force -Confirm:$false -Recurse
$VerbosePreference = $VerbosePreferenceBak
Just to see if it woudl work if it was synchronous: If you add the following code after your foreach does it work as expected? Line1:
Write-Host "Press any key to continue ..."
Line2:
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
– Kerry – 2011-05-30T23:23:25.293And during the test I am obviously assuming that you will not "press any key to continue" until you manually confirm that the zip process has completed. – Kerry – 2011-05-31T03:53:04.787
@Kerry: it actually works as expected when I add your manual test – Steve B – 2011-05-31T08:28:35.313