Вы должны пройти вложенную структуру папок внутри архива почтового индекса и извлекать каждый файл по отдельности. Рекурсивная функция - это обычный способ делать такие вещи. Что-то вроде этого (непроверенные):
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: Copyright (с) 1999-2016 Игорь Павлов: 2016-05-10
Использование: 7z < команда > [< переключатели > ...] < имя_архива > [<file_names> ...] [< @listfiles ... >]
< Команда >
а: Добавить файлы в архив
B: Benchmark
d: Удалить файлы из архива
е: Извлечение файлов из архива (без использования имен каталогов)
часа: Вычислить хеш-значения для файлов
я: Показать информацию о поддерживаемых форматах
л: Список содержимого архива
р-н: Переименование файлов в архиве
т: целостность испытания архива
и: Обновление файлов в архив
х Распакуйте файлы с полными путями
...
Другие упаковщики, вероятно, имеют аналогичный вариант.
Edit: Если вы просто хотите, чтобы извлечь вещи из определенной подпапки внутри 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)
Если вы «Копирование [чужого кода] (http://serverfault.com/a/201604/134295) было бы неплохо, если бы вы хотя бы дали им кредит за это. –