Expressingx
Expressingx

Reputation: 1572

PowerShell extract folder content from zip

I have multiple folders, let's say they are Folder1, Folder2, Folder3, etc. Inside everyone of them there is .zip file named like the folder name. So Folder1.zip, Folder2.zip, Folder3.zip, etc. Inside every zip there is path like Content/1/a/5/t/ZIPNAME/a/b/c/temp. The path is the same except where ZIPNAME is the zip currently iterating. temp folder has the files I need to copy to newly created folder like the .zip name. How can I achive that?

This is what I got at the moment. Iterating over every folder, getting the zip and opening it. How to get the content from the zip file and copy it to new folder?

    Set-Location -Path $(BaseDeployPath)
    Add-Type -AssemblyName System.IO.Compression.FileSystem

    Get-ChildItem -Recurse -Directory | ForEach-Object {
          $zipPath = Get-ChildItem $_.FullName -Filter *.zip
          $zip = [System.IO.Compression.ZipFile]::OpenRead($zipPath)

          $contentPath = ???

          $zip.Entries | Get-Content $contentPath
    }

    # close ZIP file
    $zip.Dispose()
}

Upvotes: 0

Views: 535

Answers (1)

Ansgar Wiechers
Ansgar Wiechers

Reputation: 200313

Please take a look at the documentation. The OpenRead() method returns a ZipArchive object, whose Entries property holds a collection of ZipArchiveEntry objects. These objects have (among other things) a property FullName with the relative path of the item inside the archive, hence you should be able to select the file you want to process like this:

$temp = 'Content/1/a/5/t/ZIPNAME/a/b/c/temp/'

$zip = [IO.Compression.ZipFile]::OpenRead($zipPath)
$entries = $zip.Entries | Where-Object { $_.FullName.StartsWith($temp) -and $_.Name }

The additional clause -and $_.Name excludes directory entries (which have an empty Name property) from the result.

The documentation also lists a method ExtractToFile() which supposedly allows extracting entries to files. However, that method wasn't available on my testbox. Not sure whether it's just not available in PowerShell or if it was added in a more recent version of the .Net framework.

You can extract files the old-fashioned way, though:

$entries | ForEach-Object {
    $dstPath = Join-Path 'C:\destination\folder' $_.Name

    $src = $_.Open()
    $dst = New-Object IO.FileStream $dstPath, 'Create', 'Write', 'Read'
    $src.CopyTo($dst)
    $src.Close(); $src.Dispose()
    $dst.Close(); $dst.Dispose()
}

Upvotes: 1

Related Questions