Home > database >  How to extract all zip files in subfolders in same folder using powershell
How to extract all zip files in subfolders in same folder using powershell

Time:03-20

I have a nested folder structure for example like this (it's a lot more for simplicity I put an example)

 - folder1
    - folderA
       a.zip
    - folderB
       b.zip 

I want to unzip all zip files in same folder and delete the original zip file.

so my expected output is like

 - folder1
    - folderA
       - a
         files in a.zip
    - folderB
       - b
         files in b.zip

I can get list of all zip files by Get-ChildItem '.' -R -Filter *.zip command Then also I can pipe it to unzip like

Get-ChildItem '.' -R -Filter *.zip | Expand-Archive -Force -DestinationPath c:\a

which giving a fixed destination path Also I can able to get the folder name of each zip file by

 Get-ChildItem '.' -R -Filter *.zip | select -ExpandProperty DirectoryName

also I tried

Get-ChildItem '.' -R -Filter *.zip | Expand-Archive -Force -DestinationPath $_.DirectoryName

and

Get-ChildItem '.' -R -Filter *.zip | Expand-Archive -Force -DestinationPath %{$_.DirectoryName}

also 
Get-ChildItem '.' -R -Filter *.zip | Expand-Archive -Force -DestinationPath {$_.DirectoryName}

But I can't find a way to pass the DirectoryName to Expand-Archive command

CodePudding user response:

I found the solution in case someone else has same issue

Get-ChildItem '.' -R -Filter *.zip | ForEach-Object {
     Expand-Archive $_.FullName "$($_.DirectoryName)/$($_.Basename)" -Force
     Remove-Item $_.FullName
}

CodePudding user response:

You can call the Directory property of the FileInfo objects outputted by Get-ChildItem to get the DirectoryInfo object of the parent folder of these files, then you can call the FullName property of the parents to get the destination folder.

In theory, this could work using -PipelineVariable instead of a ForEach-Object loop but I haven't personally tested it.

$ErrorActionPreference = 'Stop'

Get-ChildItem '.' -R -Filter *.zip | ForEach-Object {
    try {
        Expand-Archive -LiteralPath $_.FullName -DestinationPath $_.Directory.FullName -Force
        Remove-Item -LiteralPath $_.FullName
    }
    catch {
        Write-Warning $_.Exception.Message
    }
}
  • Related