2017-01-24 13 views
0

Я использую скрипт powershell для автоматизации архивации каталога и его подкаталогов. Я использую очень простойAnomoly с io.compression.zipfile в Powershell

Add-Type -AssemblyName "system.io.compression.filesystem" 
    [io.compression.zipfile]::CreateFromDirectory($d, $destinationFilename) 

По большей части это делает именно то, что мне нужно для этого; но в последнее время возникает проблема с пустыми подкаталогами. Эти пустые подкаталоги каким-то образом сжаты как файлы, а не каталоги.

  1. Во-первых, кто-нибудь еще столкнулся с этим?
  2. Является ли проблема связана с этим .Net API, или есть ли в окружающей среде проблема?
  3. Должен ли я использовать другую версию функции :: CreateFromDirectory?

Благодарим за помощь!

+0

Рассмотрено https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.archive/compress-archive? – jessehouwing

+0

Я играю, чтобы попробовать. Благодаря! Использует ли он что-то другое, кроме библиотеки .Net framework? – halciber

+0

Можете ли вы описать структуру каталогов, для которой это происходит? Кажется, не реплицируется –

ответ

2

Я использую этот сценарий Брайана, который делает то, что он говорит, и он должен соответствовать вашему требованию.

Есть много параметров, которые вы можете использовать как тип сжатия, метки время, подтверждает

# Purpose: Creates a .zip file of a file or folder. 
# 
# Sample: zipstuff.ps1 -target "C:\Projects\wsubi" -zip_to "C:\Users\Bryan\Desktop\wsubi" [-compression fast] [-timestamp] [-confirm] 
# 
# Params: 
# -target: The file or folder you would like to zip. 
# 
# -zip_to: The location where the zip file will be created. If an old version 
# exists, it will be deleted. 
# 
# -compression (optional): Sets the compression level for your zip file. Options: 
# a. fast - Higher process speed, larger file size (default option). 
# b. small - Slower process speed, smaller file size. 
# c. none - Fastest process speed, largest file size. 
# 
# -add_timestamp (optional): Applies a timestamp to the .zip file name. 
# By default, no timestamp is used. 
# 
# -confirm (optional): When provided, indicates that you would like to be 
# prompted when the zip process is finished. 
# 
# |Info| 

[CmdletBinding()] 
Param (
    [Parameter(Mandatory=$true,Position=0)] 
    [string]$target, 

    [Parameter(Mandatory=$true,Position=1)] 
    [string]$zip_to, 

    [Parameter(Mandatory=$false,Position=2)] 
    [ValidateSet("fast","small","none")] 
    [string]$compression, 

    [Parameter(Mandatory=$false,Position=3)] 
    [bool]$timestamp, 

    [Parameter(Mandatory=$false,Position=4)] 
    [bool]$confirm 
) 

#-----------------------------------------------------------------------------# 
function DeleteFileOrFolder 
{ Param([string]$PathToItem) 

    if (Test-Path $PathToItem) 
    { 
    Remove-Item ($PathToItem) -Force -Recurse; 
    } 
} 

function DetermineCompressionLevel{ 
[Reflection.Assembly]::LoadFile('C:\WINDOWS\System32\zipfldr.dll') 
Add-Type -Assembly System.IO.Compression.FileSystem 
    $CompressionToUse = $null; 

    switch($compression) 
    { 
    "fast" {$CompressionToUse = [System.IO.Compression.CompressionLevel]::Fastest} 
    "small" {$CompressionToUse = [System.IO.Compression.CompressionLevel]::Optimal} 
    "none" {$CompressionToUse = [System.IO.Compression.CompressionLevel]::NoCompression} 
    default {$CompressionToUse = [System.IO.Compression.CompressionLevel]::Fastest} 
    } 

    return $CompressionToUse; 
} 

#-----------------------------------------------------------------------------# 
Write-Output "Starting zip process..."; 

if ((Get-Item $target).PSIsContainer) 
{ 
    $zip_to = ($zip_to + "\" + (Split-Path $target -Leaf) + ".zip"); 
} 
else{ 

    #So, the CreateFromDirectory function below will only operate on a $target 
    #that's a Folder, which means some additional steps are needed to create a 
    #new folder and move the target file into it before attempting the zip process. 
    $FileName = [System.IO.Path]::GetFileNameWithoutExtension($target); 
    $NewFolderName = ($zip_to + "\" + $FileName) 

    DeleteFileOrFolder($NewFolderName); 

    md -Path $NewFolderName; 
    Copy-Item ($target) $NewFolderName; 

    $target = $NewFolderName; 
    $zip_to = $NewFolderName + ".zip"; 
} 

DeleteFileOrFolder($zip_to); 

if ($timestamp) 
{ 
    $TimeInfo = New-Object System.Globalization.DateTimeFormatInfo; 
    $CurrentTimestamp = Get-Date -Format $TimeInfo.SortableDateTimePattern; 
    $CurrentTimestamp = $CurrentTimestamp.Replace(":", "-"); 
    $zip_to = $zip_to.Replace(".zip", ("-" + $CurrentTimestamp + ".zip")); 
} 

$Compression_Level = (DetermineCompressionLevel); 
$IncludeBaseFolder = $false; 

[Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem"); 
[System.IO.Compression.ZipFile]::CreateFromDirectory($target, $zip_to, $Compression_Level, $IncludeBaseFolder); 

Write-Output "Zip process complete."; 

if ($confirm) 
{ 
    write-Output "Press any key to quit ..."; 
    $quit = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown"); 
} 

Использования:

zipstuff.ps1 -target "C:\Projects\wsubi" -zip_to "C:\Users\Bryan\Desktop\wsubi" [-compression fast] [-timestamp] [-confirm] 

Надеется, что это помогает.

+1

Вау! Спасибо Ранадип, я очень ценю этот пример. Я собираюсь попробовать это сейчас. Вы столкнулись с проблемой, с которой я столкнулся? Если это так, устранил ли этот скрипт проблему? – halciber

+0

@halciber: Я знаю ограничения для сети точек, поэтому я начал использовать 'zipfldr.dll'. Если его там нет, вы можете загрузить его извне и можете указать путь, как я дал в скрипте 'C: \ WINDOWS \ System32 \ zipfldr.dll' :) –