2012-06-13 10 views
23

Tworzę plik schematu bazy danych nocnej i chciałbym umieścić wszystkie pliki tworzone każdego wieczoru, po jednym dla każdej bazy danych, w folderze i skompresować ten folder. Mam skrypt PowerShell, który tworzy schemat. Tylko skrypt kreacji db, a następnie dodaje wszystkie pliki do nowego folderu. Problem leży w części kompresji tego procesu.Tworzenie skompresowanego/skompresowanego folderu w systemie Windows przy użyciu Powershell lub wiersza polecenia

Czy ktoś ma pojęcie, czy można to osiągnąć za pomocą wstępnie zainstalowanego narzędzia Windows, które obsługuje kompresję folderów?

Najlepiej byłoby użyć tego narzędzia, jeśli to możliwe, a nie jak 7zip (nie mam ochoty instalować 7zip na serwerze każdego klienta i może to zająć IT lata, jeśli o to poproszę).

+0

Myślę, że to wyjaśnia twoje opcje: http://richardspowershellblog.wordpress.com/2007/06/02/powershell-and-compressed-files/ – David

+1

Dziękuję bardzo! To było proste i łatwe rozwiązanie. Wskazówki dla kogoś, kto może natknąć się na ten wątek. Pobierz rozszerzenia społeczności PowerShell od: http://pscx.codeplex.com/downloads Wyodrębnij pliki, a następnie przenieś katalog do: C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ Moduły. Następnie zaimportuj moduł, wykonując polecenie: Import-Module Pscx – TechDawg270

Odpowiedz

19

Oto kilka funkcji związanych z ZIP, które nie zależą od rozszerzeń: Compress Files with Windows PowerShell.

Główną funkcją że byłbyś prawdopodobnie zainteresowany jest:

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 
    } 
} 

Zastosowanie:

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

Jest jedno zastrzeżenie: NameSpace() funkcją shell.application obiektu nie otwiera się plik zip do pisania, jeśli ścieżka nie jest absolutna. Tak więc, jeśli podałeś względną ścieżkę do Add-Zip, nie powiedzie się ona z błędem zerowym, więc ścieżka do pliku zip musi być bezwzględna.

Albo możesz po prostu dodać $zipfilename = resolve-path $zipfilename na początku funkcji.

+0

To zadziałało i doceniam terminową odpowiedź, ale myślę, że pobieranie i instalowanie rozszerzeń społeczności PowerShell i posiadanie dostępnego polecenia jest łatwiejsze/łatwiejsze metoda osiągnięcia funkcjonalności. – TechDawg270

+0

@ TechDawg270: Zgadzam się - przeważnie właśnie napisałem to ze względu na kompletność. – voithos

3

To kompresuje. \ W treści do. ​​\ Out.zip z System.IO.Packaging.ZipPackage wzorując 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

Używane odpowiedź voithos' do plików zip w powershell, tylko jeden problem przy użyciu funkcji Add-Zip problem Start-sleep -milliseconds 500 powodował problemy, jeśli plik nie mógł zostać w całości skompresowany w tym czasie -> następny zaczynający się przed zakończeniem spowodował błędy i niektóre pliki nie zostały spakowane.

Więc po zabawie przez chwilę, najpierw próbuje uzyskać licznik będzie sprawdzić liczbę $ zipPackage.Items() i kontynuuje po tym jak liczba przedmiotów wzrosła (co nie działało, ponieważ zwróciłoby 0 w w niektórych przypadkach, gdy nie powinno) Zauważyłem, że zwróci 0, jeśli pakiet nadal kopiuje/kopiuje pliki (myślę, haha). Dodano prostą pętlę while z początkowym snem wewnątrz, czekając, aż zipPackage.Items(). Będzie niezerową wartością przed kontynuowaniem i wydaje się, że to rozwiązuje problem.

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

Korzystanie PowerShell w wersji 3.0:

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

Nadzieja to pomaga.

+4

To nie jest cmdlet programu PowerShell. –

21

Natywny sposób korzystania z najnowszej platformy .NET 4.5 ramy, ale całkowicie wyposażone mniej:

utworzenia:

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

ekstrakcji:

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

Jak wspomniano, całkowicie wyposażone mniej, więc nie oczekuj nadpisać flagę.

+1

To jest eleganckie. Mieć upvote .. – deepelement

+0

Mam odmowę dostępu do tego rozwiązania :(Czy masz pomysł, aby to wymusić? – Jerome2606

+0

@ Jerome2606 ... następnie udostępnić ścieżkę. Również jak wspomniano, "nie oczekuj nadpisania flagi" – sonjz

4

Od PowersShell 5 jest cmdlet Compress-Archive, który wykonuje to zadanie po wyjęciu z pudełka.

Powiązane problemy