Compactar apenas arquivos usando o powershell

4

Estou tentando compactar todos os arquivos em um único diretório para uma pasta diferente como parte de uma rotina de backup simples.

O código é executado, mas não produz um arquivo zip:

$srcdir = "H:\Backup"
$filename = "test.zip"
$destpath = "K:\"

$zip_file = (new-object -com shell.application).namespace($destpath + "\"+ $filename)
$destination = (new-object -com shell.application).namespace($destpath)

$files = Get-ChildItem -Path $srcdir

foreach ($file in $files) 
{
    $file.FullName;
    if ($file.Attributes -cne "Directory")
    {
        $destination.CopyHere($file, 0x14);
    }
}

Alguma idéia de como estou dando errado?

    
por SteB 07.12.2012 / 16:50

2 respostas

5

Isso funciona em V2, deve funcionar em V3 também:

$srcdir = "H:\Backup"
$zipFilename = "test.zip"
$zipFilepath = "K:\"
$zipFile = "$zipFilepath$zipFilename"

#Prepare zip file
if(-not (test-path($zipFile))) {
    set-content $zipFile ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
    (dir $zipFile).IsReadOnly = $false  
}

$shellApplication = new-object -com shell.application
$zipPackage = $shellApplication.NameSpace($zipFile)
$files = Get-ChildItem -Path $srcdir | where{! $_.PSIsContainer}

foreach($file in $files) { 
    $zipPackage.CopyHere($file.FullName)
#using this method, sometimes files can be 'skipped'
#this 'while' loop checks each file is added before moving to the next
    while($zipPackage.Items().Item($file.name) -eq $null){
        Start-sleep -seconds 1
    }
}
    
por 09.12.2012 / 10:44
5

Eu descobri duas maneiras adicionais de fazer isso e estou incluindo-as como referência:

Usando o .net framework 4.5 (como sugerido por @MDMarra):

[Reflection.Assembly]::LoadWithPartialName( "System.IO.Compression.FileSystem" )
[System.AppDomain]::CurrentDomain.GetAssemblies()
$src_folder = "h:\backup"
$destfile = "k:\test.zip"
$compressionLevel = [System.IO.Compression.CompressionLevel]::Optimal
$includebasedir = $false
[System.IO.Compression.ZipFile]::CreateFromDirectory($src_folder, $destfile, $compressionLevel, $includebasedir)

Isso funcionou muito bem na minha máquina de desenvolvimento Win7 e é provavelmente a melhor maneira de fazer isso, mas o .Net 4.5 só é suportado no Windows Server 2008 (ou posterior), minha máquina de implantação é o Windows Server 2003.

Usando uma ferramenta de zip de linha de comando:

function create-zip([String] $aDirectory, [String] $aZipfile)  
{  
  [string]$PathToZipExe = "K:\zip.exe";  
  & $PathToZipExe "-r" $aZipfile $aDirectory;  
}

create-zip "h:\Backup\*.*" "K:\test.zip"

Eu baixei o info-zip e o chamei com os locais de origem e destino como parâmetros.
Isso funcionou bem & foi muito fácil de configurar, mas exigiu uma dependência externa.

    
por 10.12.2012 / 12:29