1

I'm writing a powershell script in which I would like to .zip a directory with 2 subdirectories. In one of the subdirectories I would like to exclude another directory.

myDirectory
-- sub 1
--- sub 1.1
--- sub 1.2
-- sub 2
--- sub 2.1
--- sub 2.2

I wrote this script but it isn't working. Can anyone give me a hint or tell me what I'm doing wrong?

$ChildItemPath = "myDirectory"

$Date = [DateTime]::Now.ToString("yyyyMMdd-HHmmss")
$Exclude = @("myDirectory/sub 2/sub 2.1")

$DestinationPath = "Archive-v" + $Date

$CompressPath = Get-ChildItem -Path $ChildItemPath -Exclude $Exclude

Compress-Archive -Path $CompressPath -DestinationPath $DestinationPath -update

the .bat/.ps1 file is in the same directory as 'myDirectory'

-------------------------- EDIT 19:55 -------------------------- Solution of suggested by Reza works fine when subfolder is pretty 'small'. I'm trying to exclude 'node_modules' from a AngularClient-dir.

So the final .zip file contains a 'serverside'-dir: vs217 asp.net core project and a 'clientside'-dir: angular4 project without the node_modules

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
dashed
  • 59
  • 1
  • 10

2 Answers2

1

To exclude some subfolders of a folder when creating a zip file, as an option you can copy the folder excluding those subfolders to a temp folder in temp directory of windows. Then zip the temp folder:

$inputFolder = "C:\MyDirectory"
$excludeFolders = @("\Sub1\Sub1-2", "\Sub2\Sub2-2")
$ouputFileName="C:\MyFile.zip"

$tempFolder = [System.IO.Path]::GetTempFileName()
Remove-Item $tempFolder -Force
New-Item -Type  Directory -Path $tempFolder -Force
$exclude =@()
$excludeFolders | ForEach-Object {
 $exclude+=(Join-Path $inputFolder $_) 
 Get-ChildItem (Join-Path $inputFolder $_) -Recurse | 
  ForEach-Object{$exclude+=$_.FullName}}
Get-ChildItem $inputFolder -Recurse | Where-Object { $_.FullName -notin $exclude} |
 Copy-Item -Destination {Join-Path $tempFolder $_.FullName.Substring($inputFolder.length)}

Get-ChildItem $tempFolder |
Compress-Archive -DestinationPath $ouputFileName -Update
# Remove-Item $tempFolder -Force -Recurse
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
  • Unfortunaly this takes a while since I'm trying to exclude a 'node_modules'-dir... And that's no gain of time. – dashed Dec 06 '17 at 18:39
  • I made it faster. You also can comment the last remove command and let the windows delete the folder whenever needs space. The delete command will also take some time. – Reza Aghaei Dec 06 '17 at 19:19
  • Pay attention, I updated the script. The update is not just commenting the last line. I also changed the way that I copied the files to temp directory. Previously, I was copying the excluded files as well and then deleting them, but now I don't copy them. – Reza Aghaei Dec 07 '17 at 07:57
  • Hi Reza, I just tried your edited script but still the script is no 5min running and not done yet ... I'll post details in a new reply – dashed Dec 07 '17 at 08:04
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/160684/discussion-between-emiel-and-reza-aghaei). – dashed Dec 07 '17 at 08:04
  • Unfortunately at the moment I don't have any other improvement to suggest. But I'll share any other improvement if I did. – Reza Aghaei Dec 07 '17 at 08:13
  • Just for your information you also can rely on 3rd party libraries to do so, which usually leads to a faster solution. – Reza Aghaei Dec 07 '17 at 08:13
  • Thanks anyway Reza! I've delete my answer/reply. – dashed Dec 07 '17 at 08:16
1

I know this is an old post, but I just wrote my own piece of script to Zip a Node.js Azure Function skipping node_modules folder. It's fast as it doesn't even go through the folders to skip.

Disclaimer: it won't filter 2nd level or deeper folders in the directory tree as it's enough for my use case

#Create temporary directory to work with
$OutputFolderName = "HOLA - Any name of course"
$tempFolderPath = [System.IO.Path]::GetTempPath()
$tempFolderToCopyTo = New-Item -Path $tempFolderPath -ItemType "directory" -Name $OutputFolderName

#Copy all folders to the temporary location, except the ones to exclude
$InputFolderPath = "Full path to the folder to copy"
$InputFoldersToSkip = @("node_modules", ".vscode")
$childItems = Get-ChildItem -Path $InputFolderPath
foreach ($child in $childItems) {
  if ($child.Name -in $InputFoldersToSkip) {
    continue
  }
  Copy-Item -Path $child.FullName -Destination $tempFolderToCopyTo -Recurse
}

#open file explorer there
Invoke-Item $tempFolderToCopyTo.PSPath


#Zip it!
$inputItem = Get-Item -Path $InputFolderPath
$compressParams = @{
  Path= "$($tempFolderToCopyTo.PSPath)\*"
  CompressionLevel = "Fastest"
  DestinationPath = "$($tempFolderToCopyTo.PSPath)/$($inputItem.Name)"
}
Compress-Archive @compressParams

#After using the Zip, delete the temp folder
  Remove-Item $tempFolderToCopyTo -Force -Recurse
Andres Biarge
  • 370
  • 4
  • 15