Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <#
- .SYNOPSIS
- Extracts a specific folder and its contents from a ZIP archive.
- .DESCRIPTION
- This PowerShell script extracts a folder from a ZIP archive and is directly executable.
- It can extract a folder in one of two ways:
- 1. By providing the full, known path to the folder within the ZIP file using -FolderPathInZip.
- 2. By searching for a folder by its name anywhere within the ZIP archive using -FindFolderByName.
- .PARAMETER ZipFilePath
- The full path to the source .ZIP file.
- .PARAMETER FolderPathInZip
- (ParameterSet: ByPath) The full path to the folder inside the ZIP file that you want to extract. e.g., 'path/to/MyFolder'.
- .PARAMETER FindFolderByName
- (ParameterSet: ByName) The name of the folder to search for and extract. The script will extract the first match it finds. e.g., 'MyFolder'.
- .PARAMETER DestinationPath
- The path to the directory where the folder should be extracted.
- .EXAMPLE
- # Example 1: Extracting by known full path
- PS C:\> .\Extract-SpecificFolderFromZip.ps1 -ZipFilePath "C:\archive.zip" -FolderPathInZip "data/logs/today" -DestinationPath "C:\temp"
- # Example 2: Searching for a folder by name
- PS C:\> .\Extract-SpecificFolderFromZip.ps1 -ZipFilePath "C:\archive.zip" -FindFolderByName "today" -DestinationPath "C:\temp"
- #>
- [CmdletBinding(DefaultParameterSetName='ByPath')]
- param(
- [Parameter(Mandatory=$true)]
- [string]$ZipFilePath,
- [Parameter(Mandatory=$true, ParameterSetName='ByPath')]
- [string]$FolderPathInZip,
- [Parameter(Mandatory=$true, ParameterSetName='ByName')]
- [string]$FindFolderByName,
- [Parameter(Mandatory=$true)]
- [string]$DestinationPath
- )
- try {
- # Add the required .NET assembly to work with ZIP files
- Add-Type -AssemblyName System.IO.Compression.FileSystem
- if (-not (Test-Path $ZipFilePath -PathType Leaf)) {
- Write-Error "The specified ZIP file does not exist: $ZipFilePath"
- return
- }
- if (-not (Test-Path $DestinationPath -PathType Container)) {
- Write-Verbose "Destination path not found. Creating directory: $DestinationPath"
- New-Item -ItemType Directory -Force -Path $DestinationPath | Out-Null
- }
- $zip = [System.IO.Compression.ZipFile]::OpenRead($ZipFilePath)
- Write-Verbose "Successfully opened ZIP file: $ZipFilePath"
- $targetFolderPathInZip = $null
- if ($PSCmdlet.ParameterSetName -eq 'ByName') {
- Write-Host "Searching for folder named '$FindFolderByName'..."
- # Find directory entries (ending with /) and get the one that matches the name
- $foundEntry = $zip.Entries | Where-Object {
- $_.FullName.EndsWith('/') -and ($_.FullName.TrimEnd('/').Split('/')[-1] -eq $FindFolderByName)
- } | Select-Object -First 1
- if ($foundEntry) {
- $targetFolderPathInZip = $foundEntry.FullName.TrimEnd('/')
- Write-Host "Found folder at: $targetFolderPathInZip"
- } else {
- Write-Warning "Could not find any folder named '$FindFolderByName' in the archive."
- $zip.Dispose()
- return
- }
- } else { # ByPath
- $targetFolderPathInZip = $FolderPathInZip
- }
- # Normalize the user-provided path to use forward slashes, which is what ZipFile entries use.
- $normalizedFolderPath = $targetFolderPathInZip.Replace('\', '/')
- # Append a slash to ensure we match a directory, not a file with a similar name.
- $folderPathInZipForSearch = "$normalizedFolderPath/"
- $entries = $zip.Entries | Where-Object { $_.FullName.StartsWith($folderPathInZipForSearch, [System.StringComparison]::OrdinalIgnoreCase) }
- if ($entries.Count -eq 0) {
- Write-Warning "No items found at path '$targetFolderPathInZip' in the ZIP archive."
- $zip.Dispose()
- return
- }
- Write-Host "Found $($entries.Count) files and folders to extract from '$targetFolderPathInZip'."
- $parentPathInZip = [System.IO.Path]::GetDirectoryName($normalizedFolderPath).Replace('\', '/')
- foreach ($entry in $entries) {
- $relativePath = $entry.FullName
- if (-not [string]::IsNullOrEmpty($parentPathInZip)) {
- $relativePath = $entry.FullName.Substring($parentPathInZip.Length + 1)
- }
- $fullDestinationPath = Join-Path $DestinationPath $relativePath
- $directoryName = [System.IO.Path]::GetDirectoryName($fullDestinationPath)
- if ($directoryName -and (-not (Test-Path $directoryName))) {
- New-Item -ItemType Directory -Path $directoryName -Force | Out-Null
- }
- if ($entry.Name -ne "") {
- Write-Verbose "Extracting $($entry.FullName) to $fullDestinationPath"
- [System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $fullDestinationPath, $true)
- }
- }
- Write-Host "Extraction complete."
- Write-Host "The folder '$targetFolderPathInZip' has been extracted to '$DestinationPath'"
- }
- catch {
- Write-Error "An error occurred: $_"
- }
- finally {
- if ($zip) {
- $zip.Dispose()
- }
- }
- # --- Example Usage ---
- # To use this script:
- # 1. Save it as a .ps1 file (e.g., Extract-SpecificFolderFromZip.ps1).
- # 2. Open a PowerShell terminal and navigate to the directory where you saved the file.
- # 3. You may need to change your execution policy: Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
- # 4. Call the script with your parameters as shown in the examples above.
Advertisement
Add Comment
Please, Sign In to add comment