PwSh.Fw.Archive.psm1
Add-Type -Assembly System.IO.Compression.FileSystem <# .SYNOPSIS List the files contained in an archive .DESCRIPTION Long description .PARAMETER Path Full path to the archive file .PARAMETER PassThru If specified, Get-ArchiveContent will return whole archive file object. If not specified, Get-ArchiveContent will return file list .EXAMPLE archive.zip | Get-ArchiveContent .NOTES Inspired by @url https://stackoverflow.com/questions/43715949/powershell-extract-specific-files-folders-from-a-zipped-archive #> function Get-ArchiveContent { [CmdletBinding()] [OutputType([String])] Param ( [Parameter(Mandatory = $true, ValueFromPipeLine = $true)][string]$Path, [switch]$PassThru ) Begin { Write-EnterFunction } Process { if (!(Test-FileExist $Path)) { Write-Fatal "Archive '$Path' not found." } # $archive = Get-Item -Path $Path #extract list entries for dir myzipdir/c/ into myzipdir.zip $zip = [IO.Compression.ZipFile]::OpenRead($Path) $entries = $zip.Entries #free object $zip.Dispose() if ($PassThru) { return $entries } else { return $entries.fullname } } End { Write-LeaveFunction } } <# .SYNOPSIS Expand a single from an archive .DESCRIPTION Extract only one specified file from an archive. .PARAMETER Path Path to the archive file .PARAMETER DestinationPath Destination path where to extract files .PARAMETER Files Exact filename to extract. The path must be relative to the root of the archive. Wildcard are not allowed .PARAMETER Force If specified, erase existing files .PARAMETER PassThru If specified, return filesystem object of files extracted. If not specified, return a list of path/files extracted .EXAMPLE "archive.zip" | Expand-SingleFileFromArchive -File "README.md" .EXAMPLE "archive.zip" | Expand-SingleFileFromArchive -File "src/path/to/file.c" This example extract the file 'file.c' from the "archive.zip" file, located in the "src/path/to" folder inside the archive. .NOTES Inspired by @url https://stackoverflow.com/questions/43715949/powershell-extract-specific-files-folders-from-a-zipped-archive #> function Expand-SingleFileFromArchive { [CmdletBinding()] [OutputType([Boolean], [System.IO.FileInfo])] Param ( [Parameter(Mandatory = $true, ValueFromPipeLine = $true)][string]$Path, [Parameter(Mandatory = $false, ValueFromPipeLine = $false)][string]$DestinationPath, [Parameter(Mandatory = $true, ValueFromPipeLine = $false)][string]$File, [switch]$Force, [switch]$PassThru ) Begin { Write-EnterFunction } Process { $rc = $false if (!(Test-FileExist $Path)) { Write-Fatal "Archive '$Path' not found." } $archive = Get-Item -Path $Path if ([string]::IsNullOrEmpty($DestinationPath)) { $DestinationPath = "$($archive.Directory)/$($archive.BaseName)" } #create dir for result of extraction $FileName = Split-Path $File -Leaf if ($Force) { if (Test-FileExist "$DestinationPath/$FileName") { Remove-Item -Path "$DestinationPath/$FileName" -Confirm:$false -Force:$Force } $null = New-Item -ItemType Directory -Path "$DestinationPath" -Force:$Force -ErrorAction SilentlyContinue } #extract list entries for dir myzipdir/c/ into myzipdir.zip try { $zip = [IO.Compression.ZipFile]::OpenRead($Path) $entry = $zip.GetEntry($File) if ($null -ne $entry) { #extraction [IO.Compression.ZipFileExtensions]::ExtractToFile( $entry, "$DestinationPath/$($entry.Name)", $Force) $rc = $? } else { eerror "File '$File' not found in archive '$($archive.Name)'" eerror "Try to Get-ArchiveContent to see what's inside." eerror "Remember, -File must be the full path to file from the archive point of view." $rc = $false } } catch { eerror $_ $rc = $false } finally { #free object $zip.Dispose() } if ($PassThru) { if ($rc) { return "$DestinationPath/$($entry.Name)" } else { return $rc } } else { return $rc } } End { Write-LeaveFunction } } |