Comment créer une archive zip avec PowerShell?
est-il possible de créer une archive zip en utilisant PowerShell?
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" .
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.
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
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...
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"
é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 .
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)
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.
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
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
}
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.
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
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)
}
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.."
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()
}
}
}
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
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'); }"
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 .
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
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.
voici une solution native pour ps v5, en utilisant cmdlet Compress-Archive
création de fichiers Zip en utilisant PowerShell
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.
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.
ce script itère tous les répertoires et zip chacun
Get-ChildItem-Attributes d / foreach {write-zip $ .Nom " $ ($ .Nom).zip"}