Est-il possible de créer une archive zip à l'aide de PowerShell?
Est-il possible de créer une archive zip à l'aide de PowerShell?
Réponses:
Si vous vous dirigez vers CodePlex et récupérez les extensions de communauté PowerShell , vous pouvez utiliser leur write-zip
applet de commande.
Puisque
CodePlex est en mode lecture seule en préparation de l'arrêt
vous pouvez accéder à la galerie PowerShell .
write-zip [input file/folder] [output file]
Une alternative PowerShell pure 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)
}
Passez simplement le chemin complet vers l'archive zip que vous souhaitez créer et le chemin complet vers le répertoire contenant les fichiers que vous souhaitez compresser.
Ajout Compress-Archive
et Expand-Archive
applets de commande PowerShell v5.0 . 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
Compress-Archive
description: "... la taille de fichier maximale que vous pouvez compresser en utilisant Compress-Archive est actuellement de 2 Go. Il s'agit d'une limitation de l'API sous-jacente" Cependant, si vous utilisez, System.IO.Compression.ZipFile
vous pouvez contourner cette limitation.
System.IO.Compression.ZipFile
. Si le framework .NET que vous utilisez n'a pas cette limite, le CmdLet ne doit pas atteindre cette limite. J'ai vérifié dans le code.
-OutputPath
paramètre.
Une manière native avec le dernier framework .NET 4.5, mais entièrement sans fonctionnalités:
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és, ne vous attendez donc pas à un indicateur de remplacement .
MISE À JOUR: Voir ci-dessous pour les autres développeurs qui ont développé cela au fil des ans ...
Installez 7zip (ou téléchargez la version de 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 ceci:
create-7zip "c:\temp\myFolder" "c:\temp\myFolder.zip"
& "C:\Program Files\7-Zip\7z.exe" a -tzip ($file.FullName+".zip") $file.FullName
Le lot a changé depuis la publication de la réponse initiale. Voici quelques-uns des derniers exemples utilisant la commande Compress-Archive .
Commande pour créer un nouveau fichier d'archive Draft.zip
, en compressant deux fichiers, Draftdoc.docx
et diagram2.vsd
, spécifié par le Path
paramètre. 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 pour créer un nouveau fichier d'archive Draft.zip
, en compressant deux fichiers, Draft doc.docx
et Diagram [2].vsd
, spécifié par le LiteralPath
paramètre. 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 d'archive,, Draft.zip
dans le C:\Archives
dossier. Le nouveau fichier d'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 .zip
automatiquement l' extension au nom de fichier.
Edit two - Ce code est un kluge laid et laid des temps anciens. Tu n'en veux pas.
Cela compresse le contenu de .\in
to .\out.zip
avec System.IO.Packaging.ZipPackage en 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 fichiers plus volumineux, peut-être> 10 Mo, YMMV. Quelque chose à voir avec les preuves du domaine d'application et le stockage isolé. L' approche .NET 4.5 plus conviviale fonctionne bien avec PS v3, mais voulait plus de mémoire dans mon cas. Pour utiliser .NET 4 à partir de PS v2, les fichiers de configuration nécessitent un ajustement non pris en charge .
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)
Voici une solution native pour PowerShell v5, à l'aide de l'applet de commande Compress-Archive
Création de fichiers Zip à l'aide de PowerShell .
Voir également 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
Pour la compression, j'utiliserais une bibliothèque (7-Zip est bon comme le suggère Michal ).
Si vous installez 7-Zip , le répertoire installé contiendra 7z.exe
ce qui est une application console.
Vous pouvez l'invoquer directement et utiliser n'importe quelle option de compression de votre choix.
Si vous souhaitez vous engager avec la DLL, cela devrait également être possible.
7-Zip est un logiciel gratuit et open source.
Et alors System.IO.Packaging.ZipPackage
?
Cela nécessiterait .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
Pourquoi personne ne regarde la documentation ?? Il existe une méthode prise en charge pour créer un fichier zip vide et y ajouter des fichiers individuels intégrés dans la même bibliothèque .NET 4.5 que 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 des questions.
C'est vraiment obscur mais ça marche. 7za.exe est une 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
}
Si quelqu'un a besoin de compresser 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
Voici le code de travail, compresser 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.."
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 souhaitez créer.
SourceDirectory: chemin complet vers le répertoire contenant les fichiers que vous souhaitez compresser.
Voici une version légèrement améliorée de la réponse de sonjz, elle ajoute une option d'écrasement.
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)
}
Cela devrait également fonctionner pour compresser un seul fichier sans utiliser de dossier temporaire et en utilisant .Net 4.5 natif, converti à partir de C # à partir de cette réponse StackOverflow . Il utilise une syntaxe plus agréable à partir d' 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()
}
}
}
shell.application
entreprise ou 7-Zip / autres utilitaires distincts. J'aime aussi la Using-Object
fonction, bien que j'aie opté pour une approche plus courte et rapide sans cela.
J'utilise cet extrait pour vérifier mon dossier de sauvegardes de base de données pour les fichiers de sauvegarde pas encore compressés, les compresser à l'aide de 7-Zip, et enfin supprimer les *.bak
fichiers pour économiser de l'espace disque. Les fichiers d'avis sont classés par longueur (du plus petit au plus grand) avant la compression pour éviter que certains fichiers ne soient pas 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 .
Si vous avez installé 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;
}
Signification des arguments: afzip crée une archive zip, df supprime des fichiers, ep1 ne crée pas de chemin de répertoire complet dans l'archive
Voici un exemple de ligne de commande complet pour lancer depuis cmd.exe ou depuis 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
Chargement du [System.IO.IOException]
classe et utiliser ses méthodes est une étape importante pour supprimer les erreurs indésirables, car il s'agit d'une classe non native de PowerShell, alors attendez-vous à divers contextes d'erreurs sans elle.
J'ai contrôlé mon script par erreur sur le T, mais j'ai obtenu beaucoup de sortie supplémentaire de «fichier existe» en utilisant la [System.IO.Compression.ZipFile]
classe
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 d'E / S, comme accéder aux fichiers qui existent déjà, attraper cette erreur et la diriger vers un fichier journal que je gère avec un programme plus grand.
Les commandes de ligne de commande complètes dans Windows pour compresser et extraire le répertoire 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 l'extraction:
powershell.exe -nologo -noprofile -command "& { Add-Type -A 'System.IO.Compression.FileSystem';[IO.Compression.ZipFile]::ExtractToDirectory('C:\Indus.zip','C:\Indus'); }"
Les roches d'approche ionique:
https://dotnetzip.codeplex.com/wikipage?title=PS-Examples
prend en charge les mots de passe, d'autres méthodes de cryptage, etc.