Est-il possible de créer une archive Zip à l'aide de PowerShell?
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 .
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.
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
_
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 ...
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"
É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 .
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)
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.
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
Voici une solution native pour PowerShell v5, à l'aide de la cmdlet Compress-Archive
Cré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
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 .
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
}
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.
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
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)
}
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.."
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()
}
}
}
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'); }"
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 .
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
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.
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.