使用PowerShell从.zip文件中删除文件

6
我将编写一段 Powershell 脚本,用于从 .zip 文件中删除文件。在我的 .zip 文件中,我有 test.txt(最新的)、test1.txt(较旧的)、test2.txt……testN.txt(最老的),它们的文件大小都不同(或者在 Powershell 中称为 Length)。我想保留其中的 2G 或更小的文件,并删除其余的文件。需要从最老的文件开始删除。由于 .zip 文件可能非常大,最好不要解压缩并重新压缩。
有没有办法实现这个目标?
非常感谢。

你打算使用什么来进行压缩?第三方工具?还是.Net类? - vonPryz
抱歉,我不太明白你的问题。.zip文件已经存在于服务器上。 - Payson
PowerShell没有内置的支持zip文件管理的功能。您需要一些工具来处理zip文件。 - vonPryz
哦,我不知道那个。谢谢。你有什么工具推荐吗?有关于压缩的教程或文档吗?再次感谢。 - Payson
2个回答

12

采用这个VBScript解决方案

$zipfile = 'C:\path\to\your.zip'
$files   = 'some.file', 'other.file', ...
$dst     = 'C:\some\folder'

$app = New-Object -COM 'Shell.Application'
$app.NameSpace($zipfile).Items() | ? { $files -contains $_.Name } | % {
  $app.Namespace($dst).MoveHere($_)
  Remove-Item (Join-Path $dst $_.Name)
}

如果您已安装了.NET Framework 4.5,类似以下代码也可以正常工作:
[Reflection.Assembly]::LoadWithPartialName('System.IO.Compression')

$zipfile = 'C:\path\to\your.zip'
$files   = 'some.file', 'other.file', ...

$stream = New-Object IO.FileStream($zipfile, [IO.FileMode]::Open)
$mode   = [IO.Compression.ZipArchiveMode]::Update
$zip    = New-Object IO.Compression.ZipArchive($stream, $mode)

($zip.Entries | ? { $files -contains $_.Name }) | % { $_.Delete() }

$zip.Dispose()
$stream.Close()
$stream.Dispose()

Entries 集合中筛选项周围的括号是必需的,否则后面的 Delete() 将修改集合。这将阻止从集合中读取(和因此删除)其他项。造成的错误信息如下:

在枚举集合时发生错误: 已修改集合;
可能无法执行枚举操作。
位于第 1 行第 1 字符
+ $zip.Entries | ? { $filesToRemove -contains $_.Name } | % { $_.Delete() }
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Collecti...ipArchiveEntry]:Enumerator) [], RuntimeException
    + FullyQualifiedErrorId : BadEnumeration

2
使用7-Zip,一个免费的Zip工具。Technet sample演示了如何在Powershell中使用7-Zip创建zip归档文件。
学习正确的命令以获取您的zip内容列表,并使用d命令从存档中删除文件。

1
我认为这是最透明的选择,尽管它需要一个外部程序。 - trainmaster
2
你本可以在这里添加实际的代码片段,因为最终它只是一个基于以下命令的一行代码:7z.exe d file.zip file-to-exclude - cregox
这与问题无关,需要通过编程实现,而不是使用第三方图形用户界面应用程序。 - Space Bear
@SpaceBear 7zip有一个命令行界面。现在,Compress-Archve可以做到,但是这是在Powershell 5.0之后引入的 - 比这个问题晚了三年。 - vonPryz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接