Jak utworzyć archiwum zip za pomocą PowerShell?

244

Czy można utworzyć archiwum zip za pomocą programu PowerShell?

Walentin Wasiljew
źródło
jakaś próbka z pełnym kodem źródłowym?
Kiquenet,

Odpowiedzi:

124

Jeśli przejdziesz do CodePlex i przejmiesz rozszerzenia społeczności PowerShell , możesz użyć ich polecenia write-zipcmdlet.

Od

CodePlex jest w trybie tylko do odczytu w ramach przygotowań do zamknięcia

możesz przejść do Galerii PowerShell .

Matt Hamilton
źródło
114
Tak, i używa 7z jako biblioteki podstawowej dla większości poleceń cmdlet kompresji. Wiem, ponieważ to zaimplementowałem;) +1
x0n 21.07.2009
1
lol dobra robota, x0n. Zaimplementowałem dostawcę sklepu z paszami w PSCX. Nieco mniej praktyczne, ale mnóstwo zabawy. :)
Matt Hamilton
1
Jeśli używa 7z, czy można skompresować za pomocą hasła?
mack
1
@SemiDementedwrite-zip [input file/folder] [output file]
joshschreuder,
9
Powershell 5 jest wyposażony w polecenia cmdlet Compress-Archive, które tworzą .zip blogs.technet.microsoft.com/heyscriptingguy/2015/08/13/…
Benoit Patra
255

Czysta alternatywa PowerShell, która działa z PowerShell 3 i .NET 4.5 (jeśli możesz go użyć):

function ZipFiles( $zipfilename, $sourcedir )
{
   Add-Type -Assembly System.IO.Compression.FileSystem
   $compressionLevel = [System.IO.Compression.CompressionLevel]::Optimal
   [System.IO.Compression.ZipFile]::CreateFromDirectory($sourcedir,
        $zipfilename, $compressionLevel, $false)
}

Po prostu podaj pełną ścieżkę do archiwum zip, które chcesz utworzyć, i pełną ścieżkę do katalogu zawierającego pliki, które chcesz spakować.

petrsnd
źródło
1
Czy to rzeczywiście potrzebuje Powershell 3.0, czy tylko .net 4.5? Wygląda mi bardzo lekko na rzeczywiste funkcje PowerShell, zamiast tego jest to po prostu programowanie .net.
bwerks
@bwerks patrz część „edytuj” tutaj
Noam
Szukałem sposobu kompresji pojedynczego dużego pliku, ale najwyraźniej nie ma na to metody. Musiałem napisać kod, który utworzyłby nowy katalog, skopiowałem tam pojedynczy plik, skompresowałem ten katalog do nowego pliku zip, a następnie usunę katalog do wyczyszczenia.
Baodad
1
@Baodad, zobacz moją odpowiedź.
Dherik
Powinienem był przeczytać, że potrzebuję pełnej ścieżki. Chłopak, który był mylący! BTW to powinna być zaakceptowana odpowiedź
Kolob Canyon
244

Dodatki Compress-Archivei polecenia Expand-Archivecmdlet programu PowerShell v5.0 . Strony, do których prowadzą linki, mają pełne przykłady, ale ich istotą jest:

# Create a zip file with the contents of C:\Stuff\
Compress-Archive -Path C:\Stuff -DestinationPath archive.zip

# Add more files to the zip file
# (Existing files in the zip file with the same name are replaced)
Compress-Archive -Path C:\OtherStuff\*.txt -Update -DestinationPath archive.zip

# Extract the zip file to C:\Destination\
Expand-Archive -Path archive.zip -DestinationPath C:\Destination
Brant Bobby
źródło
11
PowerShell v5.0 został oficjalnie wydany teraz. Jest również wyposażony w system Windows 10.
Ohad Schneider,
Teraz dostępne tutaj: microsoft.com/en-us/download/details.aspx?id=50395
starlocke
2
Z akapitu 2 Compress-Archiveopisu: „... maksymalny rozmiar pliku, który można skompresować za pomocą Compress-Archive, wynosi obecnie 2 GB. Jest to ograniczenie podstawowego interfejsu API”. Jeśli jednak użyjesz System.IO.Compression.ZipFile, możesz ominąć to ograniczenie.
AMissico,
2
Limit 2 GB został odziedziczony System.IO.Compression.ZipFile. Jeśli używana platforma .NET nie ma tego limitu, CmdLet nie powinien przekroczyć tego limitu. Zweryfikowałem w kodzie.
TravisEz13
2
@Pramod nie ma -OutputPathparametru.
BrainSlugs83
57

Natywny sposób z najnowszą platformą .NET 4.5, ale całkowicie pozbawiony funkcji:

Kreacja:

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

Ekstrakcja:

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

Jak wspomniano, całkowicie pozbawiony funkcji, więc nie oczekuj flagi zastępowania .

AKTUALIZACJA: Zobacz poniżej innych programistów, którzy rozwijali się w tym przez lata ...

sonjz
źródło
Dlaczego miałbyś używać metody pozbawionej cech?
Pluto
Powinna to być zaakceptowana odpowiedź w kolejności daty opublikowania i precedensu. Co do zaktualizowanego komentarza - istnieje naprawdę wiele sposobów na zrobienie tego teraz. Potrzebuję tej funkcjonalności i korzystam z PowerShell 4, pierwszą rzeczą, którą znalazłem, jest natywny sposób. To było dobre pytanie w 2009 roku. Nadal sądzę, że w pierwotnym pytaniu mogły zostać przedstawione dalsze badania.
DtechNet,
45

Zainstaluj 7zip (lub pobierz wersję wiersza polecenia) i użyj tej metody PowerShell:

function create-7zip([String] $aDirectory, [String] $aZipfile){
    [string]$pathToZipExe = "$($Env:ProgramFiles)\7-Zip\7z.exe";
    [Array]$arguments = "a", "-tzip", "$aZipfile", "$aDirectory", "-r";
    & $pathToZipExe $arguments;
}

Możesz to tak nazwać:

create-7zip "c:\temp\myFolder" "c:\temp\myFolder.zip"
Karl Glennon
źródło
6
Jeśli 7zip jest na twojej drodze, wszystko, co musisz napisać, to „& 7z c: \ temp \ myFolder c: \ temp \ myFolder.zip”
aboy021
5
Jeśli nie chcesz go instalować, możesz zamiast tego pobrać wersję wiersza polecenia. (Wystarczy spojrzeć na stronę pobierania 7-zip). Jest to po prostu plik wykonywalny, a składnia polecenia jest taka sama. Plik wykonywalny ma jednak inną nazwę; z jakiegoś powodu to 7za.exe. Zrobiłem to przy wielu projektach i nigdy się nie zawiodłem.
jpmc26
Próbowałem z narzędziami .net i Powershell przez zbyt długi czas, aż do przejścia do ścieżki 7zip, która zadziałała od razu. Prosta pętla foreach na pliku $ & "C:\Program Files\7-Zip\7z.exe" a -tzip ($file.FullName+".zip") $file.FullName
załatwia sprawę
17

Lot zmienił się od czasu opublikowania pierwszej odpowiedzi. Oto niektóre z najnowszych przykładów użycia polecenia Compress-Archive .

Polecenie utworzenia nowego pliku archiwum Draft.zippoprzez kompresję dwóch plików Draftdoc.docxi diagram2.vsdokreślone przez Pathparametr. Poziom kompresji określony dla tej operacji to Optymalny.

Compress-Archive -Path C:\Reference\Draftdoc.docx, C:\Reference\Images\diagram2.vsd -CompressionLevel Optimal -DestinationPath C:\Archives\Draft.Zip

Polecenie, aby utworzyć nowy plik archiwum, Draft.zipkompresując dwa pliki Draft doc.docxi Diagram [2].vsdokreślone przez LiteralPathparametr. Poziom kompresji określony dla tej operacji to Optymalny.

Compress-Archive -LiteralPath 'C:\Reference\Draft Doc.docx', 'C:\Reference\Images\Diagram [2].vsd'  -CompressionLevel Optimal -DestinationPath C:\Archives\Draft.Zip

Polecenie utworzenia nowego pliku archiwum Draft.zipw C:\Archivesfolderze. Nowy plik archiwum zawiera każdy plik w folderze C: \ Reference , ponieważ zamiast określonych nazw plików w parametrze Path użyto znaku zastępczego .

Compress-Archive -Path C:\Reference\* -CompressionLevel Fastest -DestinationPath C:\Archives\Draft

Command tworzy archiwum z całego folderu, C:\Reference

Compress-Archive -Path C:\Reference -DestinationPath C:\Archives\Draft

PowerShell automatycznie dodaje .ziprozszerzenie do nazwy pliku.

Krishna Prasad Yalavarthi
źródło
15

Edytuj dwa - Ten kod to brzydka, brzydka kluge z dawnych czasów. Nie chcesz tego.

To kompresuje zawartość .\indo .\out.zipz System.IO.Packaging.ZipPackage zgodnie z przykładem tutaj

$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()

Edycja: zawodny w przypadku większych plików, może> 10 MB, YMMV. Ma to coś wspólnego z dowodami domeny i izolowanym miejscem do przechowywania. Bardziej przyjazne podejście .NET 4.5 działa dobrze z PS v3, ale w moim przypadku potrzebowałem więcej pamięci. Aby korzystać z .NET 4 z PS v2, pliki konfiguracyjne wymagają nieobsługiwanego usprawnienia .

noam
źródło
głównym problemem ZipPackage jest to, że nie jest to zwykły plik ZIP , ale zawiera plik XML zawartości. patrz: [jak uniknąć [Content_Types] .xml w klasie ZipPackage .net - Przepełnienie stosu] ( stackoverflow.com/questions/3748970/… )
aaron
@ aaron Jeszcze jeden wspaniały powód, aby nigdy więcej tego nie używać! Masz tutaj silną rywalizację o „główny problem”;)
Noam
12

Podanie poniżej innej opcji. Spowoduje to spakowanie pełnego folderu i zapisanie archiwum do podanej ścieżki o podanej nazwie.

Wymaga platformy .NET 3 lub nowszej

Add-Type -assembly "system.io.compression.filesystem"

$source = 'Source path here'    
$destination = "c:\output\dummy.zip"

If(Test-path $destination) {Remove-item $destination}

[io.compression.zipfile]::CreateFromDirectory($Source, $destination)
karthikeyan
źródło
10

Oto natywne rozwiązanie dla programu PowerShell v5, wykorzystujące polecenie cmdlet Compress-Archive Tworzenie plików Zip za pomocą programu PowerShell .

Zobacz także dokumentację Microsoft Docs for Compress-Archive .

Przykład 1:

Compress-Archive `
    -LiteralPath C:\Reference\Draftdoc.docx, C:\Reference\Images\diagram2.vsd `
    -CompressionLevel Optimal `
    -DestinationPath C:\Archives\Draft.Zip

Przykład 2:

Compress-Archive `
    -Path C:\Reference\* `
    -CompressionLevel Fastest `
    -DestinationPath C:\Archives\Draft

Przykład 3:

Write-Output $files | Compress-Archive -DestinationPath $outzipfile
aaron
źródło
7

Do kompresji użyłbym biblioteki (7-Zip jest dobry, jak sugeruje Michał ).

Jeśli zainstalujesz 7-Zip , zainstalowany katalog będzie zawierał 7z.exeaplikację konsolową.
Możesz wywołać go bezpośrednio i użyć dowolnej opcji kompresji.

Jeśli chcesz współpracować z biblioteką DLL, powinno to być również możliwe.
7-Zip jest darmowym oprogramowaniem typu open source.

nik
źródło
2
Oto przykład użycia 7 zip z szyfrowaniem AES z Powershell: codeblog.theg2.net/2010/02/…
Greg Bray
7

Co System.IO.Packaging.ZipPackage?

Wymagałoby .NET 3.0 lub nowszej wersji.

#Load some assemblys. (No line break!)
[System.Reflection.Assembly]::Load("WindowsBase, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")

#Create a zip file named "MyZipFile.zip". (No line break!)
$ZipPackage=[System.IO.Packaging.ZipPackage]::Open("C:\MyZipFile.zip",
   [System.IO.FileMode]"OpenOrCreate", [System.IO.FileAccess]"ReadWrite")

#The files I want to add to my archive:
$files = @("/Penguins.jpg", "/Lighthouse.jpg")

#For each file you want to add, we must extract the bytes
#and add them to a part of the zip file.
ForEach ($file In $files)
{
   $partName=New-Object System.Uri($file, [System.UriKind]"Relative")
   #Create each part. (No line break!)
   $part=$ZipPackage.CreatePart($partName, "",
      [System.IO.Packaging.CompressionOption]"Maximum")
   $bytes=[System.IO.File]::ReadAllBytes($file)
   $stream=$part.GetStream()
   $stream.Write($bytes, 0, $bytes.Length)
   $stream.Close()
}

#Close the package when we're done.
$ZipPackage.Close()

przez Anders Hesselbom

Peter P.
źródło
5

Dlaczego nikt nie patrzy na dokumentację? Istnieje obsługiwana metoda tworzenia pustego pliku zip i dodawania do niego pojedynczych plików wbudowanych w tę samą bibliotekę .NET 4.5, do której wszyscy się odwołują.

Poniżej znajduje się przykład kodu:

# Load the .NET assembly
Add-Type -Assembly 'System.IO.Compression.FileSystem'

# Must be used for relative file locations with .NET functions instead of Set-Location:
[System.IO.Directory]::SetCurrentDirectory('.\Desktop')

# Create the zip file and open it:
$z = [System.IO.Compression.ZipFile]::Open('z.zip', [System.IO.Compression.ZipArchiveMode]::Create)

# Add a compressed file to the zip file:
[System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($z, 't.txt', 't.txt')

# Close the file
$z.Dispose()

Zachęcam do przejrzenia dokumentacji, jeśli masz jakieś pytania.

Pluton
źródło
2
Dziękuję za to, to jest idealne. Szczególnie w porównaniu z cmdletem Compress-Archive, który jest źle zaprojektowany i nie ma dobrego sposobu na określenie ścieżek WEWNĄTRZ zamka.
Rafael Kitover
4

To jest naprawdę niejasne, ale działa. 7za.exe to samodzielna wersja 7zip i jest dostępna z pakietem instalacyjnym.

# get files to be send
$logFiles = Get-ChildItem C:\Logging\*.* -Include *.log | where {$_.Name -match $yesterday} 

foreach ($logFile in $logFiles)
{
    Write-Host ("Processing " + $logFile.FullName)

    # compress file
    & ./7za.exe a -mmt=off ($logFile.FullName + ".7z") $logFile.FullName

}
Michał Sznajder
źródło
4

Jeśli ktoś musi skompresować pojedynczy plik (a nie folder): http://blogs.msdn.com/b/jerrydixon/archive/2014/08/08/zipping-a-single-file-with-powershell.aspx

[CmdletBinding()]
Param(
     [Parameter(Mandatory=$True)]
     [ValidateScript({Test-Path -Path $_ -PathType Leaf})]
     [string]$sourceFile,

     [Parameter(Mandatory=$True)]
     [ValidateScript({-not(Test-Path -Path $_ -PathType Leaf)})]
     [string]$destinationFile
) 

<#
     .SYNOPSIS
     Creates a ZIP file that contains the specified innput file.

     .EXAMPLE
     FileZipper -sourceFile c:\test\inputfile.txt 
                -destinationFile c:\test\outputFile.zip
#> 

function New-Zip
{
     param([string]$zipfilename)
     set-content $zipfilename 
          ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
     (dir $zipfilename).IsReadOnly = $false
}

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

dir $sourceFile | Add-Zip $destinationFile
Dherik
źródło
Ten kod opiera się na aplikacji powłoki, a następnie zgaduje 500 ms, aby czekać na zakończenie ... Nie zgadzam się, że to działa (w większości przypadków). Ale tworzy wyskakujące okienka, gdy używasz go w każdym przypadku, gdy dodanie skompresowanego pliku zajmuje trochę czasu (łatwe do odtworzenia przy dodawaniu dużych plików lub pracy z dużymi zamkami). Ponadto, jeśli jakakolwiek operacja zip jest wolniejsza niż określony czas snu, dodanie pliku i pozostawienie wyskakującego okna dialogowego nie powiedzie się. To jest straszne dla skryptów. Poparłem również inną odpowiedź, która opiera się na obiekcie COM, ponieważ nie rozwiązuje on tych pułapek.
Pluto
4

Oto działający kod, który kompresuje wszystkie pliki z folderu źródłowego i tworzy plik zip w folderze docelowym.

    $DestZip="C:\Destination\"
    $Source = "C:\Source\"

    $folder = Get-Item -Path $Source

    $ZipTimestamp = Get-Date -format yyyyMMdd-HHmmss;
    $ZipFileName  = $DestZip + "Backup_" + $folder.name + "_" + $ZipTimestamp + ".zip" 

    $Source

    set-content $ZipFileName ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18)) 
    # Wait for the zip file to be created.
    while (!(Test-Path -PathType leaf -Path $ZipFileName))
    {    
        Start-Sleep -Milliseconds 20
    } 
    $ZipFile = (new-object -com shell.application).NameSpace($ZipFileName)

    Write-Output (">> Waiting Compression : " + $ZipFileName)       

    #BACKUP - COPY
    $ZipFile.CopyHere($Source) 

    $ZipFileName
    # ARCHIVE

    Read-Host "Please Enter.."
Arkesh Patel
źródło
4
function Zip-File
    {
    param (
    [string]$ZipName,
    [string]$SourceDirectory 

    )
       Add-Type -Assembly System.IO.Compression.FileSystem
       $Compress = [System.IO.Compression.CompressionLevel]::Optimal
       [System.IO.Compression.ZipFile]::CreateFromDirectory($SourceDirectory,
            $ZipName, $Compress, $false)
    }

Uwaga:
ZipName: pełna ścieżka do pliku zip, który chcesz utworzyć.

SourceDirectory: pełna ścieżka do katalogu zawierającego pliki, które chcesz spakować.

Venkatakrishnan
źródło
3

Oto nieco ulepszona wersja odpowiedzi sonjza, dodaje opcję zastępowania.

function Zip-Files(
        [Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$false)]
        [string] $zipfilename,
        [Parameter(Position=1, Mandatory=$true, ValueFromPipeline=$false)]
        [string] $sourcedir,
        [Parameter(Position=2, Mandatory=$false, ValueFromPipeline=$false)]
        [bool] $overwrite)

{
   Add-Type -Assembly System.IO.Compression.FileSystem
   $compressionLevel = [System.IO.Compression.CompressionLevel]::Optimal

    if ($overwrite -eq $true )
    {
        if (Test-Path $zipfilename)
        {
            Remove-Item $zipfilename
        }
    }

    [System.IO.Compression.ZipFile]::CreateFromDirectory($sourcedir, $zipfilename, $compressionLevel, $false)
}
Lou O.
źródło
2
Czy mógłby Pan uściślić swoją odpowiedź, dodając nieco więcej opisu oferowanego rozwiązania?
abarisone
Wziąłem poprzednią odpowiedź i poprawiłem ją, dodając opcję zastępowania, niewiele więcej do powiedzenia!
Lou O.
3

Powinno to również działać w przypadku kompresji pojedynczego pliku bez użycia folderu tymczasowego i korzystania z natywnego programu .Net 4.5, przekonwertowanego z C # z odpowiedzi StackOverflow . Używa ładniejszej składni pobranej stąd .

Stosowanie:

ZipFiles -zipFilename output.zip -sourceFile input.sql -filename name.inside.zip.sql

Kod:

function ZipFiles([string] $zipFilename, [string] $sourceFile, [string] $filename)
{
    $fullSourceFile = (Get-Item -Path "$sourceFile" -Verbose).FullName
    $fullZipFile = (Get-Item -Path "$zipFilename" -Verbose).FullName

    Add-Type -AssemblyName System.IO
    Add-Type -AssemblyName System.IO.Compression
    Add-Type -AssemblyName System.IO.Compression.FileSystem

    Using-Object ($fs = New-Object System.IO.FileStream($fullZipFile, [System.IO.FileMode]::Create)) {
         Using-Object ($arch = New-Object System.IO.Compression.ZipArchive($fs, [System.IO.Compression.ZipArchiveMode]::Create)) {
             [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($arch, $fullSourceFile, $filename)
        }
    }
}

Za pomocą:

function Using-Object
{
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [AllowEmptyString()]
        [AllowEmptyCollection()]
        [AllowNull()]
        [Object]
        $InputObject,

        [Parameter(Mandatory = $true)]
        [scriptblock]
        $ScriptBlock
    )

    try
    {
        . $ScriptBlock
    }
    finally
    {
        if ($null -ne $InputObject -and $InputObject -is [System.IDisposable])
        {
            $InputObject.Dispose()
        }
    }
}
Mark Lopez
źródło
Doskonały. Szukałem sposobu na skompresowanie JEDNEGO pliku bez korzystania z tego shell.applicationbiznesu lub 7-Zip / innych oddzielnych narzędzi. Podoba mi się również ta Using-Objectfunkcja, chociaż bez niej wybrałem krótsze, szybkie i brudne podejście.
Charlie Joynt
2

Używam tego fragmentu, aby sprawdzić folder kopii zapasowych bazy danych w poszukiwaniu jeszcze nieskompresowanych plików kopii zapasowych, skompresować je za pomocą 7-Zip, a na koniec usunąć *.bakpliki, aby zaoszczędzić trochę miejsca na dysku. Pliki powiadomień są sortowane według długości (od najmniejszej do największej) przed kompresją, aby uniknąć kompresji niektórych plików.

$bkdir = "E:\BackupsPWS"
$7Zip = 'C:\"Program Files"\7-Zip\7z.exe'

get-childitem -path $bkdir | Sort-Object length |
where
{
    $_.extension -match ".(bak)" -and
    -not (test-path ($_.fullname -replace "(bak)", "7z"))
} |
foreach
{
    $zipfilename = ($_.fullname -replace "bak", "7z")
    Invoke-Expression "$7Zip a $zipfilename $($_.FullName)"
}
get-childitem -path $bkdir |
where {
    $_.extension -match ".(bak)" -and
   (test-path ($_.fullname -replace "(bak)", "7z"))
} |
foreach { del $_.fullname }

Tutaj możesz sprawdzić skrypt PowerShell do tworzenia kopii zapasowych, kompresji i przesyłania tych plików przez FTP .

Nathan
źródło
2

Jeśli masz zainstalowany WinRAR:

function ZipUsingRar([String] $directory, [String] $zipFileName)
{
  Write-Output "Performing operation ""Zip File"" on Target ""Item: $directory Destination:"
  Write-Output ($zipFileName + """")
  $pathToWinRar = "c:\Program Files\WinRAR\WinRar.exe";
  [Array]$arguments = "a", "-afzip", "-df", "-ep1", "$zipFileName", "$directory";
  & $pathToWinRar $arguments;
}

Znaczenie argumentów: afzip tworzy archiwum zip, df usuwa pliki, ep1 nie tworzy pełnej ścieżki katalogu w archiwum

Roman O
źródło
2

Oto kompletny przykład wiersza poleceń do uruchomienia z cmd.exe lub z ssh lub co chcesz!

powershell.exe -nologo -noprofile -command "&{ Add-Type -A 'System.IO.Compression.FileSystem' [System.IO.Compression.ZipFile]::CreateFromDirectory('c:/path/to/source/folder/', 'c:/path/to/output/file.zip');}"

pozdrowienia

Alex
źródło
2

Ładowanie [System.IO.IOException]klasy i korzystanie z jej metod jest ważnym krokiem w celu eliminacji niepożądanych błędów, ponieważ jest to klasa nienatywna dla PowerShell, więc bez niej należy oczekiwać różnych kontekstów błędów.

Skontrolowałem mój skrypt do T, ale dostałem wiele dodatkowych czerwonych wyników „plik istnieje” podczas korzystania z [System.IO.Compression.ZipFile]klasy

function zipFiles(
    [Parameter(Position=0, Mandatory=$true]
    [string] $sourceFolder,
    [Parameter(Position=1, Mandatory=$true]
    [string]$zipFileName,
    [Parameter(Position=2, Mandatory=$false]
    [bool]$overwrite)

{   
Add-Type -Assembly System.IO
Add-Type -Assembly System.IO.Compression.FileSystem

$compressionLevel = [System.IO.Compression.CompressionLevel]::Optimal

$directoryTest = (Test-Path $dailyBackupDestFolder)
$fileTest = (Test-Path $zipFileName)

if ( $directoryTest -eq $false) 
{ 
    New-Item -ItemType Directory -Force -Path $dailyBackupDestFolder 
}

     if ( $fileTest -eq $true)
     {
           if ($overwrite -eq $true ){Remove-Item $zipFileName}
     }   


    try
    {
         [System.IO.Compression.ZipFile]::CreateFromDirectory($sourceFolder,$zipFileName,$compressionLevel)       

    }
    catch [System.IO.IOException] 
    {
       Write-Output ($dateTime + ' | ' + $_.Exception.Message ) | Out-File $logFile -append -force 
    }
} 

To, co tu robię, polega na wyłapywaniu tych błędów we / wy, takich jak uzyskiwanie dostępu do plików, które już istnieją, przechwytywanie tego błędu i przekierowywanie go do pliku dziennika, który utrzymuję za pomocą większego programu.

Paul Latour
źródło
2

Pełne polecenia wiersza polecenia w systemie Windows do kompresji i wyodrębniania katalogu są następujące:

  • Do kompresji:

    powershell.exe -nologo -noprofile -command "& { Add-Type -A 'System.IO.Compression.FileSystem'; [IO.Compression.ZipFile]::CreateFromDirectory('C:\Indus','C:\Indus.zip'); }"
  • Do wyodrębnienia:

    powershell.exe -nologo -noprofile -command "& { Add-Type -A 'System.IO.Compression.FileSystem';[IO.Compression.ZipFile]::ExtractToDirectory('C:\Indus.zip','C:\Indus'); }"
Sudhir Sinha
źródło
-4

Ten skrypt iteruje wszystkie katalogi i zipuje każdy z nich

Get-ChildItem -Attributes d | foreach {write-zip $ .Name "$ ($ .Name) .zip"}

Gerardo
źródło
1
Jedyną częścią tego istotnego pytania siedmioletniego było „zapisz-zip”, co było odpowiedzią przyjętą w 2009 r.
Odrzucono