web-dev-qa-db-fra.com

Comment créer une archive Zip avec PowerShell?

Est-il possible de créer une archive Zip à l'aide de PowerShell?

230
Valentin

Si vous passez à CodePlex et récupérez la PowerShell Community Extensions , vous pouvez utiliser leur cmdlet write-Zip.

Puisque

CodePlex est en mode lecture seule en préparation de l'arrêt

vous pouvez aller à Galerie PowerShell .

117
Matt Hamilton

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 vous suffit de passer le chemin complet de l’archive Zip que vous souhaitez créer et le chemin complet du répertoire contenant les fichiers que vous souhaitez Zip.

251
petrsnd

PowerShell v5.0 ajoute Compress-Archive et Expand-Archive cmdlets. Les pages liées ont des exemples complets, mais l'essentiel 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
_
218
Brant Bobby

Une manière native avec le dernier framework .NET 4.5, mais sans aucune fonctionnalité:

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 dépourvu de fonctionnalités, ne vous attendez donc pas à un indicateur écraser.

MISE À JOUR: Voir ci-dessous pour les autres développeurs qui ont développé cela au fil des ans ...

56
sonjz

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)\7-Zip\7z.exe";
    [Array]$arguments = "a", "-tzip", "$aZipfile", "$aDirectory", "-r";
    & $pathToZipExe $arguments;
}

Vous pouvez l'appeler comme ça:

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

Éditez deux - Ce code est un kluge moche et moche des temps anciens. Tu n'en veux pas.

Ceci compresse le contenu de .\in en .\out.Zip avec System.IO.Packaging.ZipPackage à la suite de 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()

Éditez: non fiable pour les fichiers plus volumineux, peut-être> 10mb, YMMV. Quelque choseà faire avec preuve évidente et stockage isolé. Le plus convivial .NET 4.5 approche fonctionne bien à partir 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 pris en chargeTweak .

15
noam

Donner ci-dessous une autre option. Cela zippera un dossier complet et écrira l'archive dans un chemin donné avec le nom donné.

Nécessite .NET 3 ou supérieur

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

Pour la compression, je voudrais utiliser 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 console.
Vous pouvez l’appeler directement et utiliser l’option de compression de votre choix.

Si vous souhaitez utiliser la DLL, cela devrait également être possible.
7-Zip est un logiciel gratuit à code source ouvert.

7
nik

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

Il faudrait .NET 3.0 ou supérieur.

_#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

6
Peter P.

Voici une solution native pour PowerShell v5, à l'aide de la cmdlet Compress-ArchiveCréation de fichiers Zip à l'aide de PowerShell .

Voir aussi les documents Microsoft pour Compress-Archive .

Exemple 1:

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

Exemple 2:

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

Exemple 3:

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

Pourquoi personne ne regarde la documentation? Il existe une méthode prise en charge qui consiste à créer un fichier Zip vide et à y ajouter des fichiers individuels intégrés à la même bibliothèque .NET 4.5, à laquelle tout le monde se réfère.

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 à parcourez la documentation si vous avez des questions .

4
Pluto

C'est vraiment obscur, mais ça marche. 7za.exe est la version autonome de 7Zip et est disponible avec le package d'installation.

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

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

SourceDirectory: chemin d'accès complet au répertoire contenant les fichiers que vous souhaitez compresser.

4
Venkatakrishnan

Si quelqu'un doit compresser un 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
3
Dherik

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

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.

Voici le code de travail, compressant tous les fichiers d’un dossier source et créant 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.."
3
Arkesh Patel

Le lot a changé depuis la publication de la réponse initiale. Voici quelques-uns des derniers exemples utilisant la commande Compress-Archive.

Commande permettant de créer un nouveau fichier archive, Draft.Zip, en compressant deux fichiers, Draftdoc.docx et diagram2.vsd, spécifiés par le paramètre Path. Le niveau de compression spécifié pour cette opération est Optimal.

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

Commande permettant de créer un nouveau fichier archive, Draft.Zip, en compressant deux fichiers, Draft doc.docx et Diagram [2].vsd, spécifiés par le paramètre LiteralPath. Le niveau de compression spécifié pour cette opération est Optimal.

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

Commande pour créer un nouveau fichier archive, Draft.Zip, dans le dossier C:\Archives. Le nouveau fichier archive contient tous les fichiers du dossier C:\Reference, car un caractère générique a été utilisé à la place de noms de fichiers spécifiques dans le paramètre Path.

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

La commande crée une archive à partir d'un dossier entier, C:\Reference

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

PowerShell ajoute automatiquement l'extension .Zip au nom du fichier.

Cela devrait également fonctionner pour compresser un seul fichier sans utiliser de dossier temporaire ni utiliser. Net 4.5 natif, converti à partir de C # à partir de ce StackOverflow answer . Il utilise une syntaxe plus agréable tirée de ici .

Usage:

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

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

Les commandes de ligne de commande complètes dans Windows pour Compressing and Extracting Directory sont les suivantes:

  • 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 extraire:

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

J'utilise cet extrait pour vérifier le dossier de sauvegarde de ma base de données à la recherche de fichiers de sauvegarde non encore compressés, pour les compresser à l'aide de 7-Zip et enfin pour supprimer les fichiers *.bak afin d'économiser de l'espace disque. Les fichiers de notification sont classés par longueur (du plus petit au plus grand) avant la compression pour éviter que certains fichiers ne soient compressés.

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

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

2
Nathan

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

Cordialement

2
Alex

Le chargement de la classe [System.IO.IOException] et l'utilisation de ses méthodes constituent une étape importante pour supprimer les erreurs non désirées, car il s'agit d'une classe non native de PowerShell. Attendez-vous donc à divers contextes d'erreurs.

J'ai contrôlé par erreur mon script sur le T, mais j'ai obtenu beaucoup de sorties 'fichier existe' en rouge lors de l'utilisation de [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 d’attraper ces IO Erreurs, telles que l’accès à des fichiers existants, l’attraper et le diriger vers un fichier journal que je gère avec un programme plus volumineux.

2
Paul Latour

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

La signification des arguments: afzip crée une archive Zip, df supprime des fichiers, ep1 ne crée pas un chemin de répertoire complet dans une archive.

2
Roman O