it-swarm.com.de

Wie erstelle ich ein Zip-Archiv mit PowerShell?

Ist es möglich, ein Zip-Archiv mit PowerShell zu erstellen?

230
Valentin

Wenn Sie zu CodePlex gehen und sich die PowerShell Community Extensions schnappen, können Sie deren write-Zip Cmdlet.

Schon seit

CodePlex befindet sich im schreibgeschützten Modus, um das Herunterfahren vorzubereiten

sie können zu PowerShell-Galerie gehen.

117
Matt Hamilton

Eine reine PowerShell-Alternative, die mit PowerShell 3 und .NET 4.5 funktioniert (sofern Sie sie verwenden können):

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

Geben Sie einfach den vollständigen Pfad zu dem Zip-Archiv ein, das Sie erstellen möchten, und den vollständigen Pfad zu dem Verzeichnis, in dem sich die Dateien befinden, die Sie komprimieren möchten.

251
petrsnd

PowerShell v5.0 fügt hinzu: Compress-Archive und Expand-Archive Cmdlets. Die verlinkten Seiten haben vollständige Beispiele, aber der Kern davon ist:

# 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
218
Brant Bobby

Ein nativer Weg mit dem neuesten .NET 4.5-Framework, jedoch ohne jegliche Funktionen:

Schaffung:

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

Extraktion:

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

Wie bereits erwähnt, ohne jegliche Funktionen. Erwarten Sie also kein überschreiben Flag.

UPDATE: Nachfolgend finden Sie weitere Entwickler, die dies im Laufe der Jahre erweitert haben ...

56
sonjz

Installieren Sie 7Zip (oder laden Sie stattdessen die Befehlszeilenversion herunter) und verwenden Sie diese PowerShell-Methode:

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

Sie können es so nennen:

create-7Zip "c:\temp\myFolder" "c:\temp\myFolder.Zip"
43
Karl Glennon

Edit two - Dieser Code ist eine hässliche, hässliche Kluge aus alten Tagen. Du willst es nicht.

Dies komprimiert den Inhalt von .\in bis .\out.Zip mit System.IO.Packaging.ZipPackage nach dem Beispiel hier

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

Bearbeiten: nzuverlässig für größere Dateien, möglicherweise> 10 MB, YMMV. Etwaszu tun mit Appdomain-Beweisen und isoliertem Speicher. Das freundlichere .NET 4.5 Ansatz funktioniert gut von PS v3, wollte aber mehr Speicher in meinem Fall. Um .NET 4 von PS v2 zu verwenden, benötigen Konfigurationsdateien ein nicht unterstütztTweak .

15
noam

Geben Sie unten eine andere Option. Dadurch wird ein vollständiger Ordner komprimiert und das Archiv unter dem angegebenen Namen in einen angegebenen Pfad geschrieben.

Benötigt .NET 3 oder höher

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)
12
karthikeyan

Für die Komprimierung würde ich eine Bibliothek verwenden (7-Zip ist gut wie Michal schlägt vor ).

Wenn Sie 7-Zip installieren, enthält das installierte Verzeichnis 7z.exe Dies ist eine Konsolenanwendung.
Sie können es direkt aufrufen und jede gewünschte Komprimierungsoption verwenden.

Wenn Sie sich mit der DLL beschäftigen möchten, sollte dies ebenfalls möglich sein.
7-Zip ist Freeware und Open Source.

7
nik

Wie wäre es mit System.IO.Packaging.ZipPackage ?

Es würde .NET 3.0 oder höher erfordern.

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

über Anders Hesselbom

6
Peter P.

Hier ist eine native Lösung für PowerShell v5 mit dem Cmdlet Compress-ArchiveErstellen von Zip-Dateien mit PowerShell .

Siehe auch die Microsoft Docs für Compress-Archive .

Beispiel 1:

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

Beispiel 2:

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

Beispiel 3:

Write-Output $files | Compress-Archive -DestinationPath $outzipfile
6
aaron

Warum schaut niemand in die Dokumentation? Es gibt eine unterstützte Methode zum Erstellen einer leeren Zip-Datei und zum Hinzufügen einzelner Dateien in derselben .NET 4.5-Bibliothek, auf die alle verweisen.

Unten finden Sie ein Codebeispiel:

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

Ich ermutige Sie, in der Dokumentation nachzuschlagen wenn Sie Fragen haben .

4
Pluto

Das ist wirklich dunkel, funktioniert aber. 7za.exe ist eine eigenständige Version von 7Zip und ist mit dem Installationspaket verfügbar.

# 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

}
4
Michal Sznajder
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)
    }

Hinweis:
ZipName: Vollständiger Pfad der Zip-Datei, die Sie erstellen möchten.

SourceDirectory: Vollständiger Pfad zum Verzeichnis mit den Dateien, die Sie komprimieren möchten.

4
Venkatakrishnan

Wenn jemand eine einzelne Datei (und keinen Ordner) komprimieren muss: 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
3
Dherik

Hier ist eine leicht verbesserte Version der Antwort von sonjz, die eine Überschreiboption hinzufügt.

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)
}
3
Lou O.

Hier ist der Arbeitscode, der alle Dateien aus einem Quellordner komprimiert und eine Zip-Datei im Zielordner erstellt.

    $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.."
3
Arkesh Patel

Lot hat sich seit dem Absenden der ersten Antwort geändert. Hier sind einige der neuesten Beispiele, die den Befehl Compress-Archive verwenden.

Befehl zum Erstellen einer neuen Archivdatei, Draft.Zip, durch Komprimieren von zwei Dateien, Draftdoc.docx und diagram2.vsd, angegeben durch den Parameter Path. Die für diesen Vorgang angegebene Komprimierungsstufe ist Optimal.

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

Befehl zum Erstellen einer neuen Archivdatei, Draft.Zip, durch Komprimieren von zwei Dateien, Draft doc.docx und Diagram [2].vsd, angegeben durch den Parameter LiteralPath. Die für diesen Vorgang angegebene Komprimierungsstufe ist Optimal.

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

Befehl zum Erstellen einer neuen Archivdatei, Draft.Zip, in dem C:\Archives Mappe. Die neue Archivdatei enthält alle Dateien im Ordner C:\Reference, da im Parameter Path anstelle bestimmter Dateinamen ein Platzhalterzeichen verwendet wurde.

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

Befehl erstellt ein Archiv aus einem gesamten Ordner, C:\Reference

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

PowerShell fügt das .Zip Erweiterung des Dateinamens automatisch.

Dies sollte auch zum Komprimieren einer einzelnen Datei ohne Verwendung eines temporären Ordners und unter Verwendung von nativem .Net 4.5 funktionieren, das aus C # von diesem StackOverflow konvertiert wurde answer . Es verwendet eine schönere Syntax aus hier .

Verwendungszweck:

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

Code:

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

Verwenden von:

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()
        }
    }
}
3
Mark Lopez

Die vollständigen Befehlszeilenbefehle in Windows zum Komprimieren und Extrahieren von Verzeichnissen lauten wie folgt:

  • Für die Kompression:

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

    powershell.exe -nologo -noprofile -command "& { Add-Type -A 'System.IO.Compression.FileSystem';[IO.Compression.ZipFile]::ExtractToDirectory('C:\Indus.Zip','C:\Indus'); }"
    
2
Sudhir Sinha

Mit diesem Snippet überprüfe ich meinen Datenbank-Backup-Ordner auf noch nicht komprimierte Backup-Dateien, komprimiere sie mit 7-Zip und lösche schließlich das *.bak Dateien, um Speicherplatz zu sparen. Hinweisdateien werden vor der Komprimierung nach Länge (kleinste bis größte) sortiert, um zu vermeiden, dass einige Dateien nicht komprimiert werden.

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

Hier können Sie ein PowerShell-Skript zum Sichern, Komprimieren und Übertragen dieser Dateien über FTP aktivieren.

2
Nathan

Hier ein komplettes Befehlszeilenbeispiel zum Starten von cmd.exe oder von ssh oder was Sie wollen!

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');}"

Grüße

2
Alex

Das Laden der Klasse [System.IO.IOException] Und die Verwendung ihrer Methoden ist ein wichtiger Schritt, um unerwünschte Fehler zu unterdrücken, da es sich um eine Klasse handelt, die nicht in PowerShell enthalten ist. Erwarten Sie daher verschiedene Fehlerkontexte.

Ich habe mein Skript für das T fehlergesteuert, aber während der Verwendung der Klasse [System.IO.Compression.ZipFile] Wurde eine Menge zusätzlicher roter 'file exists'-Ausgaben ausgegeben

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

Was ich hier tue, ist, diese IO Fehler abzufangen, z. B. auf bereits vorhandene Dateien zuzugreifen, diesen Fehler abzufangen und ihn in eine Protokolldatei zu leiten, die ich mit einem größeren Programm verwalte.

2
Paul Latour

Falls Sie WinRAR installiert haben:

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

Die Bedeutung der Argumente: afzip erstellt ein Zip-Archiv, df löscht Dateien, ep1 erstellt keinen vollständigen Verzeichnispfad innerhalb des Archivs

2
Roman O