Wie erstelle ich ein Zip-Archiv mit PowerShell?

244

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

Valentin Vasilyev
quelle
irgendein Beispiel mit vollem Quellcode?
Kiquenet

Antworten:

124

Wenn Sie zu CodePlex wechseln und die PowerShell-Community-Erweiterungenwrite-zip herunterladen , können Sie deren Cmdlet verwenden.

Schon seit

CodePlex ist zur Vorbereitung des Herunterfahrens schreibgeschützt

Sie können zur PowerShell-Galerie gehen .

Matt Hamilton
quelle
114
Ja, und es verwendet 7z als Kernbibliothek für die meisten seiner Komprimierungs-Cmdlets. Ich weiß, weil ich es implementiert habe;) +1
x0n
1
lol gute Arbeit, x0n. Ich habe den Feed Store-Anbieter in PSCX implementiert. Etwas weniger praktisch, aber jede Menge Spaß. :)
Matt Hamilton
1
Wenn 7z verwendet wird, ist es möglich, mit einem Passwort zu komprimieren?
Mack
1
@ SemiDementedwrite-zip [input file/folder] [output file]
Joshschreuder
9
Powershell 5 kommt mit einem Compress-Archive-Cmdlet, das .zip blogs.technet.microsoft.com/heyscriptingguy/2015/08/13/… erstellt
Benoit Patra
255

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

Übergeben Sie einfach den vollständigen Pfad zu dem Zip-Archiv, das Sie erstellen möchten, und den vollständigen Pfad zu dem Verzeichnis, das die Dateien enthält, die Sie komprimieren möchten.

petrsnd
quelle
1
Benötigt dies tatsächlich Powershell 3.0 oder nur .net 4.5? Sieht für mich sehr leicht in Bezug auf die tatsächlichen Powershell-Funktionen aus, stattdessen ist es nur .net-Programmierung.
Bwerks
@bwerks siehe den 'Bearbeiten'-Teil hier
Noam
Ich habe nach einer Möglichkeit gesucht, nur eine einzelne große Datei zu komprimieren, aber anscheinend gibt es dafür keine Methode. Ich musste Code schreiben, der ein neues Verzeichnis erstellen, die einzelne Datei dort kopieren, dieses Verzeichnis in eine neue Zip-Datei komprimieren und dann das Verzeichnis löschen, um es zu bereinigen.
Baodad
1
@ Baodad, siehe meine Antwort.
Dherik
Hätte lesen sollen, dass ich den vollen Weg brauchte. Junge, das war verwirrend! Übrigens sollte dies die akzeptierte Antwort sein
Kolob Canyon
244

PowerShell v5.0 fügt hinzu Compress-Archiveund Expand-ArchiveCmdlets. Die verlinkten Seiten enthalten vollständige Beispiele, aber das Wesentliche 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
Brant Bobby
quelle
11
PowerShell v5.0 wurde jetzt offiziell veröffentlicht. Es kommt auch mit Windows 10.
Ohad Schneider
Jetzt hier verfügbar: microsoft.com/en-us/download/details.aspx?id=50395
starlocke
2
Aus Absatz 2 der Compress-ArchiveBeschreibung: "... die maximale Dateigröße, die Sie mithilfe von Compress-Archive komprimieren können, beträgt derzeit 2 GB. Dies ist eine Einschränkung der zugrunde liegenden API." Wenn Sie System.IO.Compression.ZipFilediese Option jedoch verwenden , können Sie diese Einschränkung umgehen.
AMissico
2
Das 2-GB-Limit wurde von geerbt System.IO.Compression.ZipFile. Wenn das von Ihnen verwendete .NET Framework dieses Limit nicht hat, sollte CmdLet dieses Limit nicht erreichen. Ich habe im Code verifiziert.
TravisEz13
2
@Pramod gibt es keinen -OutputPathParameter.
BrainSlugs83
57

Eine native Methode mit dem neuesten .NET 4.5-Framework, jedoch ohne 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, völlig funktionslos. Erwarten Sie also kein Überschreibungsflag .

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

sonjz
quelle
Warum sollten Sie die featureless Methode verwenden?
Pluto
Dies sollte die akzeptierte Antwort in der Reihenfolge des veröffentlichten Datums und des Präzedenzfalls sein. In Bezug auf Ihren aktualisierten Kommentar gibt es jetzt wirklich eine Vielzahl von Möglichkeiten, dies zu tun. Ich bin mit der Notwendigkeit konfrontiert, diese Funktionalität zu benötigen, und ich bin auf PowerShell 4. Das erste, was ich gefunden habe, ist der native Weg. Dies war eine gute Frage im Jahr 2009. Ich denke immer noch, dass in der Frage, als sie ursprünglich gestellt wurde, weitere Untersuchungen hätten durchgeführt werden können.
DtechNet
45

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"
Karl Glennon
quelle
6
Wenn sich 7zip in Ihrem Pfad befindet, müssen Sie nur "& 7z c: \ temp \ myFolder c: \ temp \ myFolder.zip"
schreiben
5
Wenn Sie es nicht installieren möchten, können Sie stattdessen die Befehlszeilenversion herunterladen. (Schauen Sie sich einfach die Download-Seite von 7-zip an.) Es ist nur eine ausführbare Datei, und die Befehlssyntax ist dieselbe. Die ausführbare Datei hat jedoch einen anderen Namen. Es ist 7za.exe aus irgendeinem Grund. Ich habe dies bei einer Reihe von Projekten getan und wurde nie enttäuscht.
jpmc26
Ich habe es viel zu lange mit den Tools .net und Powershell versucht, bis ich den 7zip-Pfad eingeschlagen habe, der sofort funktioniert hat. Einfache foreach-Schleife auf $ file macht den Trick& "C:\Program Files\7-Zip\7z.exe" a -tzip ($file.FullName+".zip") $file.FullName
SebK
17

Lot hat sich geändert, seit die erste Antwort veröffentlicht wurde. Hier sind einige der neuesten Beispiele mit dem Befehl Compress-Archive .

Befehl zum Erstellen einer neuen Archivdatei Draft.zipdurch Komprimieren von zwei Dateien Draftdoc.docxund diagram2.vsdangegeben durch den PathParameter. 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.zipdurch Komprimieren von zwei Dateien Draft doc.docxund Diagram [2].vsdangegeben durch den LiteralPathParameter. 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.zipim C:\ArchivesOrdner. 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 ganzen Ordner, C:\Reference

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

PowerShell hängt die .zipErweiterung automatisch an den Dateinamen an.

Krishna Prasad Yalavarthi
quelle
15

Bearbeiten Sie zwei - Dieser Code ist eine hässliche, hässliche Kluge aus alten Tagen. Du willst es nicht.

Dadurch wird der Inhalt von .\into .\out.zipmit System.IO.Packaging.ZipPackage gemäß dem hier gezeigten Beispiel komprimiert

$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: Unzuverlässig für größere Dateien, möglicherweise> 10 MB, YMMV. Etwas zu tun mit Appdomain Beweise und isoliert Lagerung. Der freundlichere .NET 4.5- Ansatz funktioniert gut mit PS v3, wollte aber in meinem Fall mehr Speicher. Um .NET 4 von PS v2, Konfigurationsdateien benötigen einen verwenden nicht unterstützten zwicken .

noam
quelle
Das Hauptproblem von ZipPackage ist, dass es keine normale ZIP- Datei ist, sondern eine Inhalts-XML-Datei enthält. Siehe: [So vermeiden Sie [Content_Types] .xml in der ZipPackage-Klasse von .net - Stack Overflow] ( stackoverflow.com/questions/3748970/… )
Aaron
@aaron Ein weiterer guter Grund, dies nie wieder zu verwenden! Sie haben harte Konkurrenz für "das Hauptproblem" hier;)
Noam
12

Geben Sie unter einer anderen Option. Dadurch wird ein vollständiger Ordner komprimiert und das Archiv in einen bestimmten Pfad mit dem angegebenen Namen 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)
karthikeyan
quelle
10

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

Siehe auch Microsoft Docs for 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
Aaron
quelle
7

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

Wenn Sie 7-Zip installieren, enthält 7z.exedas installierte Verzeichnis 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 auch möglich sein.
7-Zip ist Freeware und Open Source.

nik
quelle
2
Hier ist ein Beispiel für die Verwendung von 7 zip mit AES-Verschlüsselung von Powershell: codeblog.theg2.net/2010/02/…
Greg Bray
7

Was ist 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

Peter P.
quelle
5

Warum schaut sich niemand die Dokumentation an? Es gibt eine unterstützte Methode zum Erstellen einer leeren Zip-Datei und zum Hinzufügen einzelner Dateien, die in dieselbe .NET 4.5-Bibliothek integriert sind, 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 zu sehen , wenn Sie irgendwelche Fragen.

Pluto
quelle
2
Danke dafür, das ist perfekt. Besonders im Vergleich zum Cmdlet Compress-Archive, das schlecht gestaltet ist und keine gute Möglichkeit bietet, Pfade INNERHALB der Zip anzugeben.
Rafael Kitover
4

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

}
Michal Sznajder
quelle
4

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
Dherik
quelle
Dieser Code basiert auf einer Shell-Anwendung und schätzt dann 500 ms, um zu warten, bis er fertig ist ... Ich bin nicht anderer Meinung, dass er funktioniert (in den meisten Fällen). Es werden jedoch Popups erstellt, wenn Sie sie in jedem Fall verwenden, in dem das Hinzufügen einer komprimierten Datei einige Zeit in Anspruch nimmt (leicht reproduzierbar durch Hinzufügen großer Dateien oder Arbeiten mit großen Reißverschlüssen). Auch wenn eine Zip-Operation langsamer ist als die angegebene Ruhezeit, kann die Datei nicht hinzugefügt werden und ein Popup-Dialogfeld bleibt zurück. Das ist schrecklich für Skripte. Ich habe auch die andere Antwort abgelehnt, die auf einem COM-Objekt basiert, da diese Fallstricke nicht behoben werden.
Pluto
4

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.."
Arkesh Patel
quelle
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)
    }

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.

Venkatakrishnan
quelle
3

Hier ist eine leicht verbesserte Version der Antwort von sonjz. Sie fügt eine Überschreiboption hinzu.

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.
quelle
2
Könnten Sie bitte Ihre Antwort näher erläutern und etwas mehr Beschreibung der von Ihnen bereitgestellten Lösung hinzufügen?
Abarisone
Ich habe eine vorherige Antwort genommen und sie durch Hinzufügen einer Überschreiboption verbessert, nicht viel mehr zu sagen!
Lou O.
3

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

Verwendung:

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()
        }
    }
}
Mark Lopez
quelle
Ausgezeichnet. Ich suchte nach einer Möglichkeit, EINE Datei zu komprimieren, ohne dieses shell.applicationUnternehmen oder 7-Zip / andere separate Dienstprogramme zu verwenden. Ich mag die Using-ObjectFunktion auch, obwohl ich mich ohne diese für einen kürzeren, schnellen und schmutzigen Ansatz entschieden habe.
Charlie Joynt
2

Ich verwende dieses Snippet, um meinen Datenbanksicherungsordner auf noch nicht komprimierte Sicherungsdateien zu überprüfen, sie mit 7-Zip zu komprimieren und schließlich die *.bakDateien zu löschen , 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 überprüfen , um diese Dateien über FTP zu sichern, zu komprimieren und zu übertragen .

Nathan
quelle
2

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

Roman O.
quelle
2

Hier ein vollständiges 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

Alex
quelle
2

Das Laden der [System.IO.IOException]Klasse 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 ohne diese Klasse.

Ich habe mein Skript auf das T fehlergesteuert, aber während der Verwendung der [System.IO.Compression.ZipFile]Klasse wurde eine Menge zusätzlicher roter "Datei existiert" 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 mache, ist das Abfangen dieser E / A-Fehler, z. B. der Zugriff auf bereits vorhandene Dateien, das Abfangen dieses Fehlers und das Weiterleiten an eine Protokolldatei, die ich mit einem größeren Programm verwalte.

Paul Latour
quelle
2

Vollständige Befehlszeilenbefehle in Windows zum Komprimieren und Extrahieren von Verzeichnissen lauten wie folgt:

  • Zur Komprimierung:

    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'); }"
Sudhir Sinha
quelle
-4

Dieses Skript iteriert alle Verzeichnisse und komprimiert jedes

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

Gerardo
quelle
1
Der einzige Teil davon, der für die 7-jährige Frage relevant war, war "write-zip", was die akzeptierte Antwort im Jahr 2009 war.
Abgelehnt am