您需要遍历 zip 存档中的嵌套文件夹结构,并分别提取每个文件。递归函数是做这种事情的常用方法。像这样的东西(未经测试):
function Expand-Files($Folder, $Target) {
$Folder.Items() | ForEach-Object {
if ($_.IsFolder) {
Expand-Files $_ $Target
} else {
$Target.CopyHere($_)
}
}
}
Expand-Files $zip_file $destination
但请注意,CopyHere 是异步运行的,即调用会立即返回,而实际的复制操作可能仍在后台运行。
您也可以将嵌套文件夹树提取到一个临时目录,然后将所有文件复制到实际目标文件夹:
Get-ChildItem $destination -Recurse |
Where-Object { -not $_.PSIsContainer } |
Move-Item -Destination $actualDestination
使用这种方法(安装 .NET Framework 4.5 或更新版本),您可以放弃笨拙/易碎的 CopyHere 方法,改用 ExtractToDirectory:
Add-Type -Assembly System.IO.Compression.FileSystem
$zipfile = 'C:\path\to\your.zip'
$tempdir = "$env:TEMP\some\folder"
$destination = 'D:\Packages'
[IO.Compression.ZipFile]::ExtractToDirectory($zipfile, $tempdir)
Get-ChildItem $tempdir -Recurse |
Where-Object { -not $_.PSIsContainer } |
Move-Item -Destination $destination
Remove-Item $tempdir -Recurse -Force
或者,您可以简单地使用7-zip:
& 7z.exe e -o"$destination" "$zipfile"
来自命令帮助(强调我的):
7-Zip [32] 16.00:版权所有 (c) 1999-2016 Igor Pavlov:2016-05-10
用法:7z [...] [...] []
a : 将文件添加到存档
b : 基准
d : 从存档中删除文件
e : 从存档中提取文件(不使用目录名)
h : 计算文件的哈希值
i :显示有关支持格式的信息
l : 列出存档的内容
rn : 重命名存档中的文件
t :测试存档的完整性
u :将文件更新到存档
x : 提取具有完整路径的文件
...
其他包装商可能也有类似的选择。
编辑:如果您只想从 zip 存档中的特定子文件夹中提取内容,您可以将路径(包括嵌套路径)传递给 Namespace 方法:
$app = New-Object -COM 'Shell.Application'
$items = $app.NameSpace('C:\path\to\your.zip\folder\inside\archive').Items()
$app.NameSpace('D:\Packages').CopyHere($items)