Comment créer une archive zip avec PowerShell?

est-il possible de créer une archive zip en utilisant PowerShell?

201
demandé sur Kiquenet 2009-07-20 15:56:40

24 réponses

si vous allez sur CodePlex et de saisir le PowerShell Community Extensions , vous pouvez utiliser leur write-zip cmdlet.

depuis

CodePlex est en mode Lecture seule en préparation pour l'arrêt d'urgence

vous pouvez aller à PowerShell "Galerie 151930920" .

110
répondu Matt Hamilton 2018-08-02 12:53:35

Une alternative Pure PowerShell qui fonctionne avec PowerShell 3 et .NET 4.5 (si vous pouvez l'utiliser):

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

il suffit de passer dans le chemin d'accès complet de l'archive zip que vous souhaitez créer et le chemin complet vers le répertoire contenant les fichiers que vous souhaitez compresser.

236
répondu petrsnd 2018-05-25 13:37:53

PowerShell v5.0 ajoute Compress-Archive et Expand-Archive cmdlets. Les pages liées ont des exemples complets, mais l'essentiel de celui-ci est:

# 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
184
répondu Brant Bobby 2015-03-26 16:53:07

de façon native avec la dernière .NET 4.5 framework, mais entièrement la fonctionnalité de moins:

création:

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

Extraction:

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

comme mentionné, totalement sans fonctionnalité, donc ne vous attendez pas à un drapeau overwrite .

mise à jour: Voir ci-dessous pour les autres développeurs qui ont développé ce sujet au fil des ans...

51
répondu sonjz 2018-09-19 00:35:38

installez 7zip (ou téléchargez la version en ligne de commande à la place) et utilisez cette méthode PowerShell:

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

, Vous pouvez l'appeler comme ceci:

create-7zip "c:\temp\myFolder" "c:\temp\myFolder.zip"
37
répondu Karl Glennon 2015-03-12 16:09:17

éditer deux - ce code est un vilain, vilain kluge de vieux jours. Vous ne souhaitez pas.

Cela comprime le contenu de .\in à .\out.zip avec le système.IO.Emballage.Fermeture à glissière suivant l'exemple ici

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

Edit: peu Fiable pour les gros fichiers, peut-être >10 mo, YMMV. quelque chose à faire avec le domaine d'application des éléments de preuve et de stockage isolé. Le plus sympathique .NET 4.5 approche fonctionne bien de PS v3, mais voulait plus de mémoire dans mon cas. Pour utiliser .NET 4 à partir de PS v2, les fichiers de configuration ont besoin d'un non supporté tweak .

13
répondu noam 2017-05-23 11:47:21

donnant ci-dessous une autre option. Ceci fermera un dossier complet et écrira l'archive sur un chemin donné avec le nom donné.

nécessite .NET 3 ou plus

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)
11
répondu karthikeyan 2017-02-13 21:48:31

pour la compression, j'utiliserais une bibliothèque (7-Zip est bon comme Michal suggère ).

si vous installez 7-Zip , le répertoire installé contiendra 7z.exe qui est une application de console.

Vous pouvez l'invoquer directement et utiliser n'importe quelle option de compression que vous voulez.

si vous souhaitez vous engager avec la DLL, cela devrait également être possible.

7-Zip is freeware et open source.

6
répondu nik 2017-05-23 12:26:20

Qu'en est-il System.IO.Packaging.ZipPackage ?

Il faudrait .NET 3.0 ou supérieure.

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

via Anders Hesselbom

5
répondu Peter P. 2018-05-05 05:20:56

c'est vraiment obscur mais ça marche. 7za.exe est la version autonome de 7zip et est disponible avec le paquet install.

# 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

}
3
répondu Michal Sznajder 2009-07-20 12:20:17
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)
    }

Note:

ZipName: chemin complet du fichier Zip que vous voulez créer.

SourceDirectory: chemin Complet vers le répertoire contenant les fichiers que vous souhaitez compresser.

3
répondu Venkatakrishnan 2016-10-26 08:29:56

si quelqu'un doit zip un seul fichier (et non un dossier): 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
2
répondu Dherik 2015-04-02 11:30:07

Voici une version légèrement améliorée de la réponse de sonjz,elle ajoute une option de réécriture.

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)
}
2
répondu Lou O. 2015-04-10 08:29:44

voici le code de travail, zippant tous les fichiers d'un dossier source et créer un fichier zip dans le dossier de destination.

    $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.."
2
répondu Arkesh Patel 2016-03-21 19:38:46

cela devrait aussi fonctionner pour comprimer un seul fichier sans utiliser un dossier temp et en utilisant natif .Net 4.5, converti à partir de C# à partir de ce StackOverflow réponse . Il utilise une meilleure syntaxe en utilisant ici .

Utilisation:

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

utilisant:

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()
        }
    }
}
2
répondu Mark Lopez 2017-05-23 12:18:14

voici un exemple complet de ligne de commande à lancer à partir de cmd.exe ou de ssh ou ce que vous voulez !

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

concerne

2
répondu Alex 2016-12-02 10:24:26

les commandes complètes en ligne de commande dans Windows pour compresser et extraire le répertoire est comme suit:

  • Pour La Compression:

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

  • Pour L'Extraction:

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

2
répondu Sudhir Sinha 2018-05-05 16:33:49

J'utilise cet extrait pour vérifier mon dossier de sauvegardes de base de données pour les fichiers de sauvegarde pas encore compressé, les compresser en utilisant 7-Zip, et finalement supprimer les fichiers *.bak pour économiser de l'espace disque. Les fichiers Notice sont classés par longueur (de la plus petite à la plus grande) avant la compression pour éviter que certains fichiers ne soient compressés.

$bkdir = "E:\BackupsPWS"
Zip = 'C:\"Program Files"-Zipz.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 "Zip a $zipfilename $($_.FullName)"
}
get-childitem -path $bkdir |
where {
    $_.extension -match ".(bak)" -and
   (test-path ($_.fullname -replace "(bak)", "7z"))
} |
foreach { del $_.fullname }

ici, vous pouvez vérifier un script PowerShell pour sauvegarder, compresser et transférer ces fichiers sur FTP .

1
répondu Nathan 2014-01-01 14:36:26

dans le cas où WinRAR est installé:

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

Le sens de l'argumentation: afzip crée une archive zip, df supprime les fichiers, ep1 ne crée pas de chemin complet du répertoire à l'intérieur de l'archive

1
répondu Roman O 2014-10-06 10:12:52

charger la classe [System.IO.IOException] et utiliser ses méthodes est une étape importante afin de supprimer les erreurs indésirables, en raison du fait que c'est une classe non native de PowerShell, donc s'attendre à divers contextes d'erreurs sans elle.

j'ai contrôlé par erreur mon script vers le T, mais j'ai eu beaucoup de sortie supplémentaire rouge 'file exists' en utilisant [System.IO.Compression.ZipFile] class

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

ce que je fais ici, c'est attraper ces erreurs IO, comme accéder à des fichiers qui existent déjà, captant cette erreur et la dirigeant vers un fichier journal que je maintiens avec un programme plus grand.

1
répondu Paul Latour 2017-10-19 10:12:37

voici une solution native pour ps v5, en utilisant cmdlet Compress-Archive création de fichiers Zip en utilisant PowerShell

1
répondu aaron 2018-04-04 05:50:42

pourquoi personne ne regarde la documentation?? Il y a une méthode supportée de créer un fichier zip vide et d'y ajouter des fichiers individuels construits dans la même bibliothèque .NET 4.5 tout le monde fait référence.

voir ci-dessous pour un exemple de code:

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

je vous encourage à parcourir la documentation si vous avez tout des questions.

1
répondu Pluto 2018-09-21 08:56:49

L'ionique approche des roches:

https://dotnetzip.codeplex.com/wikipage?title=PS-Examples

supporte les mots de passe, d'autres méthodes de cryptage, etc.

-1
répondu Jonesome 2015-01-13 22:52:49

ce script itère tous les répertoires et zip chacun

Get-ChildItem-Attributes d / foreach {write-zip $ .Nom " $ ($ .Nom).zip"}

-3
répondu Gerardo 2017-03-08 19:28:39