15

I've got a need to make a .zip of each directory in a list in PowerShell. I for some reason cannot figure out how to change to each directory to run a command relative to that path though.

Here is my situation:

$dir = Get-ChildItem d:\directory | ? {$_.PSIsContainer}

$dir | ForEach-Object {
  Set-Location $_.FullName;
  Invoke-Expression "7z.exe A" +  $_.Name + ".rar " + $_.Path + "\"
}

The command is ugly, but due to the way that 7Zip seems to parse text, I had to go this way. I believe the command should make a ZIP file in each directory, with the name set equal to the directory name, and include all of the files in the directory.

It seems like I'm stuck in some PowerShell hell though where I cannot even access the values of objects for some reason.

For instance, if I echo $dir, I see my list of directories. However, if I try

gci $dir[1]

PowerShell returns nothing. It's not actually enumerating the directory path contained within the variable property, but instead trying to list the items contained within that value, which would of course be empty.

What gives?! How do I do this?

2
  • So, I found another method in a different forum. I basically needed to separate my directory navigation functions from my command building, and I was overthinking things. In fact, I'd forgotten about the ForEach ($var in $vars) method of recursing through an array. sourceforge.net/p/sevenzip/discussion/45797/thread/49a7a85b Commented Jul 16, 2013 at 17:48
  • To make your zip call tidier use an alias: Set-Alias sz "C:\Windows\7za.exe"; sz A -tzip "$($_.Name).rar" $_.Path Commented Aug 29, 2013 at 10:08

2 Answers 2

29

You don't need to set the location, you just just provide paths to 7z.exe. Also, 7zip does not compress to Rar, only decompress.

$dir = dir d:\directory | ?{$_.PSISContainer}

foreach ($d in $dir){
    $name = Join-Path -Path $d.FullName -ChildPath ($d.Name + ".7z")
    $path = Join-Path -Path $d.FullName -ChildPath "*"

    & "C:\Program Files\7-Zip\7z.exe" a -t7z $name $path
}
Sign up to request clarification or add additional context in comments.

Comments

5

If you don't want to remove the logs after zipping it, comment out the 3rd line

function zip-log {
    Compress-Archive *.log Logs.zip 
    Get-Item *.log | Remove-Item -Force 
    }

$dir = Get-ChildItem d:\directory| ? {$_.PSIsContainer}
$dir | ForEach-Object {Set-Location $_.FullName; zip-log}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.