2012-06-13 14 views
23

Estoy creando un archivo de esquema de base de datos nocturno y me gustaría poner todos los archivos creados cada noche, uno para cada base de datos, en una carpeta y comprimir esa carpeta. Tengo un script de PowerShell que crea el esquema. Solo crea el script del archivo db y luego agrega todos los archivos a una nueva carpeta. El problema se encuentra dentro de la porción de compresión de este proceso.Creando una carpeta comprimida o comprimida en Windows usando Powershell o la línea de comando

¿Alguien tiene alguna idea de si esto se puede lograr con la utilidad de Windows preinstalada que maneja la compresión de carpetas?

Sería mejor utilizar esa utilidad si es posible en lugar de algo como 7zip (no tengo ganas de instalar 7zip en el servidor de todos los clientes y puede tomar años de TI hacerlo si se los pido).

+0

Creo que esto explica sus opciones: http://richardspowershellblog.wordpress.com/2007/06/02/powershell-and-compressed-files/ – David

+1

¡Muchas gracias! Esta fue una solución limpia y fácil. Instrucciones para cualquier otra persona que pueda tropezar con este hilo. Descargue las extensiones de la comunidad de PowerShell desde: http://pscx.codeplex.com/downloads Extraiga los archivos y luego mueva el directorio a: C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ Modules. Luego importe el módulo ejecutando el comando: Import-Module Pscx – TechDawg270

Respuesta

19

Aquí hay un par de funciones relacionadas con el zip que no dependen de las extensiones: Compress Files with Windows PowerShell.

La función principal que te gustaría probablemente interesará es:

function Add-Zip 
{ 
    param([string]$zipfilename) 

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

    $shellApplication = new-object -com shell.application 
    $zipPackage = $shellApplication.NameSpace($zipfilename) 

    foreach($file in $input) 
    { 
      $zipPackage.CopyHere($file.FullName) 
      Start-sleep -milliseconds 500 
    } 
} 

Uso:

dir c:\demo\files\*.* -Recurse | Add-Zip c:\demo\myzip.zip 

Hay una advertencia: la función del objeto shell.applicationNameSpace() falla para abrir el archivo zip para escribir si el camino no es absoluto. Por lo tanto, si pasó una ruta relativa a Add-Zip, fallará con un error nulo, por lo que la ruta al archivo zip debe ser absoluta.

O simplemente podría agregar un $zipfilename = resolve-path $zipfilename al principio de la función.

+0

Esto funcionó y agradezco la respuesta oportuna, pero creo que descargar e instalar las extensiones de comunidad de PowerShell y tener la disponibilidad del comando Write-Zip es más limpio/más fácil. método de lograr la funcionalidad. – TechDawg270

+0

@ TechDawg270: Estoy de acuerdo: la mayoría de las veces solo publiqué esto para completar. – voithos

3

Esto comprime. \ En los contenidos a. \ Out.zip con System.IO.Packaging.ZipPackage siguiendo el ejemplo here

$zipArchive = $pwd.path + "\out.zip" 
[System.Reflection.Assembly]::Load("WindowsBase,Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35") 
$ZipPackage=[System.IO.Packaging.ZipPackage]::Open($zipArchive, [System.IO.FileMode]"OpenOrCreate", [System.IO.FileAccess]"ReadWrite") 
$in = gci .\in | select -expand fullName 
[array]$files = $in -replace "C:","" -replace "\\","/" 
ForEach ($file In $files) { 
    $partName=New-Object System.Uri($file, [System.UriKind]"Relative") 
    $part=$ZipPackage.CreatePart($partName, "application/zip", [System.IO.Packaging.CompressionOption]"Maximum") 
    $bytes=[System.IO.File]::ReadAllBytes($file) 
    $stream=$part.GetStream() 
    $stream.Write($bytes, 0, $bytes.Length) 
    $stream.Close() 
                } 
$ZipPackage.Close() 
1

Usado respuesta voithos' a los archivos zip arriba en PowerShell, sólo tenía un problema con la función Add-Zip, Start-sleep -milliseconds 500 causó problemas si el archivo no se pudo cerrar por completo en ese momento -> el siguiente que se iniciaba antes de completarse causaba errores y algunos archivos no se comprimían.

Así que después de jugar un poco, primero tratando de obtener un contador va a verificar el recuento de los $ zipPackage.Items() y solo continúa después de que el conteo de artículos aumentó (lo cual no funcionó ya que devolvería 0 en en algunos casos, cuando no debería). Descubrí que devolverá 0 si el paquete aún está comprimiendo/copiando los archivos (creo, jaja). Se agregó un bucle while simple con el inicio-reposo dentro de él, esperando que zipPackage.Items(). Cuente como un valor distinto de cero antes de continuar y esto parece resolver el problema.

function Add-Zip 
{ 
param([string]$zipfilename) 

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

$shellApplication = new-object -com shell.application 
$zipPackage = $shellApplication.NameSpace($zipfilename) 

foreach($file in $input) 
{ 
     $zipPackage.CopyHere($file.FullName) 
     do 
     { 
      Start-sleep -milliseconds 250 
     } 
     while ($zipPackage.Items().count -eq 0) 
} 
} 
-3

uso de PowerShell versión 3.0:

Copy-ToZip -File ".\blah" -ZipFile ".\blah.zip" -Force 

Espero que esto ayude.

+4

Este no es un cmdlet PowerShell 3. –

21

Una manera nativa con la versión más reciente de .NET 4.5 Marco, pero completamente en características menos:

Creación:

Add-Type -Assembly "System.IO.Compression.FileSystem" ; 
[System.IO.Compression.ZipFile]::CreateFromDirectory("c:\your\directory\to\compress", "yourfile.zip") ; 

Extracción:

Add-Type -Assembly "System.IO.Compression.FileSystem" ; 
[System.IO.Compression.ZipFile]::ExtractToDirectory("yourfile.zip", "c:\your\destination") ; 

Como se ha mencionado, totalmente en características menos, así que no esperamos una sobrescribir bandera.

+1

Esto es elegante. Tener un voto positivo ... – deepelement

+0

Tengo una ruta de acceso denegada con esta solución :(¿Tienes idea de forzar eso? – Jerome2606

+0

@ Jerome2606 ... luego haz accesible tu ruta. También como se mencionó, "no esperes una bandera de sobrescritura" – sonjz

4

Desde PowersShell 5 hay un cmdlet Compress-Archive que realiza la tarea de la caja.

Cuestiones relacionadas