Pete
Pete

Reputation: 11

Powershell - Unzip all zipped files in a directory as well as rename them based on the parent file names

I have a folder and set of files like so:

So the root folder contains hundreds of parent folders, each parent folder contains hundreds of files, each file contains a single zipfile with the title "export", and each zipfile contains a single .txt file, also named "export".

I need to get

  1. all of those .txt files out of the zipfiles,
  2. all of those .txt files named something unique using a known method, and
  3. and moved to a common folder location.

So far I have a few bits of the process working but nothing that does all three things. I can rename the zipfiles something unique, based on the file and parent names, by doing these two lines:

Get-ChildItem -LiteralPath 'C:\Insert Root Directory here' -Recurse | Rename-Item -NewName { $_.Parent.Name+'_'+$_.Name}

and then

Get-ChildItem -LiteralPath 'C:\Insert Root Directory here' -Filter *.zip -Recurse | Rename-Item -NewName { $_.Directory.Name+'_'+$_.Name}

Then I tried something I found on here to unzip the zipfiles, rename the .txt files they contain, and move them simultaneously to new location, but it is erroring with a "movefileinfoitemunauthorizedaccesserror microsoft.powershell.commands.moveitemcommand" error. I have tried tinkering around with it but I cannot get it to work. If remove everything after "#Move Our Temp Files" the error goes away but the outcomes is still not successful. I get a single .txt file named export in the $TempPath location. :

$ZipFilesPath = "C:\Insert Root Directory here";
#Unzip To Temp Folder Defined Here
$TempPath = "C:\Insert Location to put .txt files here"

#Create Our Temp File If It Doesnt Exist (Will Be Deleted Again)
If(!(test-path $TempPath))
{
      New-Item -ItemType Directory -Force -Path $TempPath
}

$Shell = New-Object -com Shell.Application
$Location = $Shell.NameSpace($TempPath)
$ZipFiles = Get-Childitem $ZipFilesPath -Recurse -Include *.ZIP
$FileCounter = 1

foreach ($ZipFile in $ZipFiles) {
    #Get The Base Filename without the Filepath
    $ZipFileActualName = [io.path]::GetFileNameWithoutExtension($ZipFile.FullName)
    write-host "File: "  $ZipFileActualName
    $ZipFolder = $Shell.NameSpace($ZipFile.fullname)
    $Location.Copyhere($ZipFolder.items(), 1040)
    #Move Our Temp Files
    $txtFiles = Get-ChildItem $TempPath *.txt
    $txtFiles |% {Move-Item  $_.Fullname "$UnzipPath/$ZipFileActualName.txt"}
    #Move Along to Next File
    $FileCounter++
}

Can anyone help me achieve the above? Open to any and all ideas. Thanks!

Upvotes: 1

Views: 4956

Answers (1)

Cpt.Whale
Cpt.Whale

Reputation: 5351

Expand-Archive in PS 5.1 or higher should help simplify what you're looking for:

$dst = "c:\destination"
$tmp = "c:\temporary"

# Get a list of all the zip files
Foreach ($zipfile in (Get-ChildItem "C:\source\*.zip" -Recurse)) {

  # Extract the 'extract.txt' file to your temp folder
  Expand-Archive -Path $zipfile -DestinationPath $tmp -Force

  # Move the extract.txt to your destination folder
  # And rename based on the source folder and zip file name
  Move-Item -Path "$tmp\export.txt" -Destination "$dst\$($zipfile.Directory.BaseName)$($zipfile.BaseName).txt"

}

The MoveItem error is likely due to this path being incorrect: "$UnzipPath/$ZipFileActualName.txt". It doesn't look like you set $UnzipPath anywhere in your script?

Upvotes: 1

Related Questions