Come creare un archivio zip con PowerShell?

È ansible creare un archivio zip usando PowerShell?

Se vai su CodePlex e prendi le estensioni della community di PowerShell , puoi usare il loro cmdlet write-zip .

Da

CodePlex è in modalità di sola lettura in preparazione per l’arresto

puoi andare alla Galleria PowerShell .

Una pura alternativa PowerShell che funziona con PowerShell 3 e .NET 4.5 (se è ansible utilizzarlo):

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

Basta passare il percorso completo all’archivio zip che si desidera creare e il percorso completo alla directory contenente i file che si desidera chiudere.

PowerShell v5.0 aggiunge cmdlet Compress-Archive e Expand-Archive . Le pagine collegate hanno esempi completi, ma il succo è:

 # 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 

Un modo nativo con il più recente framework .NET 4.5, ma completamente privo di funzionalità:

Creazione:

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

Estrazione:

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

Come detto, totalmente senza funzionalità, quindi non aspettatevi un flag di sovrascrittura .

Installa 7zip (o scarica la versione da riga di comando) e usa questo metodo 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; } 

Puoi chiamarlo così:

 create-7zip "c:\temp\myFolder" "c:\temp\myFolder.zip" 

Modifica due : questo codice è un brutto e brutto affare dei vecchi tempi. Non lo vuoi.

Questo comprime il contenuto di .\in a .\out.zip con System.IO.Packaging.ZipPackage seguendo l’esempio qui

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

Modifica: inaffidabile per file più grandi, forse> 10mb, YMMV. Qualcosa che ha a che fare con prove appdomain e archiviazione isolata. L’ approccio più amichevole .NET 4.5 funziona bene con PS v3, ma nel mio caso voleva più memoria. Per utilizzare .NET 4 da PS v2, i file di configurazione richiedono un tweak non supportato .

Dando sotto un’altra opzione. Questo comprimerà una cartella completa e scriverà l’archivio in un determinato percorso con il nome specificato.

Richiede .NET 3 o successivo

 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) 

Per la compressione, vorrei usare una libreria (7-Zip è buono come suggerisce Michal ).

Se si installa 7-Zip , la directory installata conterrà 7z.exe che è un’applicazione console.
Puoi invocarlo direttamente e utilizzare qualsiasi opzione di compressione che desideri.

Se si desidera impegnarsi con la DLL, dovrebbe essere ansible anche.
7-Zip è freeware e open source.

Che dire di System.IO.Packaging.ZipPackage ?

Richiede .NET 3.0 o versione successiva.

 #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

Questo è veramente oscuro ma funziona. 7za.exe è la versione standalone di 7zip ed è disponibile con il pacchetto di installazione.

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

Se qualcuno deve comprimere un singolo file (e non una cartella): 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 

Ecco una versione leggermente migliorata della risposta di sonjz, aggiunge un’opzione di sovrascrittura.

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

Ecco il codice di lavoro, zippare tutti i file da una cartella di origine e creare un file zip nella cartella di destinazione.

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

Nota:
ZipName: percorso completo del file zip che si desidera creare.

SourceDirectory: percorso completo alla directory contenente i file che si desidera chiudere.

Questo dovrebbe funzionare anche per comprimere un singolo file senza usare una cartella temporanea e usando nativo .Net 4.5, convertito da C # da questa risposta StackOverflow. Usa una syntax più bella presa da qui .

Uso:

ZipFiles -zipFilename output.zip -sourceFile input.sql -filename name.inside.zip.sql

Codice:

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

usando:

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

Ecco un esempio completo da riga di comando per lanciare da cmd.exe o da ssh o quello che vuoi!

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

Saluti

I comandi della riga di comando completi in Windows per la compressione e l’estrazione della directory sono i seguenti:

  • Per compressione:

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

  • Per estrarre:

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

Io uso questo snippet per controllare la mia cartella di backup del database per i file di backup non ancora compressi, comprimerli usando 7-Zip e infine eliminare i file *.bak per risparmiare spazio su disco. I file di avviso sono ordinati per lunghezza (dal più piccolo al più grande) prima della compressione per evitare che alcuni file non vengano compressi.

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

Qui puoi controllare uno script PowerShell per eseguire il backup, comprimere e trasferire quei file tramite FTP .

Nel caso in cui hai installato 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; } 

Il significato degli argomenti: afzip crea un archivio zip, df cancella i file, ep1 non crea il percorso completo della directory all’interno dell’archivio

Il caricamento della class [System.IO.IOException] e l’utilizzo dei suoi metodi è un passo importante per eliminare gli errori indesiderati, poiché si tratta di una class non nativa di PowerShell, quindi aspettatevi vari contesti di errori senza di essa.

Ho controllato il mio script in modo errato sul T, ma ho ottenuto un output rosso extra “file exists” durante l’utilizzo della class [System.IO.Compression.ZipFile]

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

Quello che sto facendo qui è catturare questi errori di I / O, come l’accesso ai file che esistono già, catturare quell’errore e indirizzarlo a un file di log che sto mantenendo con un programma più grande.

ecco una soluzione nativa per ps v5, utilizzando cmdlet Compress-Archive Creazione di file Zip usando PowerShell

L’approccio ionico oscilla:

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

supporta password, altri metodi crittografici, ecc.

Questo script esegue iterazioni su tutte le directory e zip ciascuna

Get-ChildItem -Attributes d | foreach {write-zip $ .Name “$ ($ .Name) .zip”}