Как создать zip-архив с помощью PowerShell?


Answers

Чистая альтернатива Powershell, которая работает с Powershell 3 и .NET 4.5 (если вы можете ее использовать):

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

Просто перейдите в полный путь к zip-архиву, который вы хотите создать, и полный путь к каталогу, содержащему файлы, которые вы хотели бы заархивировать.

Question

Можно ли создать zip-архив с помощью PowerShell?




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

Заметка:
ZipName: полный путь к Zip-файлу, который вы хотите создать.

SourceDirectory: полный путь к каталогу, содержащему файлы, которые вы хотели бы заархивировать.







Изменить два - этот код является уродливым, уродливым kluge из старых дней. Ты не хочешь этого.

Это сжимает содержимое .\out.zip to .\out.zip с помощью System.IO.Packaging.ZipPackage, следующего за примером here

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

Изменить: Unreliable для больших файлов, возможно> 10mb, YMMV. Something связано с доказательством апдомена и изолированным хранилищем. Дружелюбный approach .NET 4.5 отлично работает с PS v3, но в моем случае требуется больше памяти. Чтобы использовать .NET 4 из PS v2, для конфигурационных файлов требуется unsupported tweak .




Вот полный пример командной строки для запуска из cmd.exe или из ssh или того, что вы хотите!

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

С уважением




Если у вас установлен 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;
}

Значение аргументов: afzip создает zip-архив, df удаляет файлы, ep1 не создает полный путь к каталогу в архиве




Вот немного улучшенная версия ответа sonjz, она добавляет опцию перезаписи.

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



Для сжатия я бы использовал библиотеку (7-Zip хорош, как предлагает Michal ).

Если вы устанавливаете 7-Zip , установленный каталог будет содержать 7z.exe который является консольным приложением.
Вы можете вызвать его напрямую и использовать любой параметр сжатия, который вы хотите.

Если вы хотите взаимодействовать с DLL, это также должно быть возможно.
7-Zip - бесплатная и открытая программа.




Это действительно неясно, но работает. 7za.exe - автономная версия 7zip и доступна с установочным пакетом.

# 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

}



Полные команды командной строки в Windows для сжатия и извлечения каталога выглядят следующим образом:

  • Для сжатия:

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

  • Для извлечения:

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




Родной способ с последней платформой .NET 4.5, но полностью не имеющий значения:

Создание:

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

Экстракция:

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

Как уже упоминалось, полностью бескомпромиссны, поэтому не ожидайте флаг перезаписи .