All,
I am trying to compress, append to the zip name, and then delete HEIC files from multiple subfolders. Here's an example layout:
Years
|2019
||09.01.19 - Visiting the Zoo
|||Photo1.HEIC
|||Photo1.JPG
|||Photo2.HEIC
|||Photo2.JPG
|||Photo3.HEIC
|||Photo3.JPG
|2020
||09.02.20 - Pumpkin Picking
|||DSC01.HEIC
|||DSC01.JPG
|||DSC02.HEIC
|||DSC02.JPG
|||DSC03.HEIC
|||DSC03.JPG
|2021
||09.04.21 - Whitewater Rafting
|||IMG01.HEIC
|||IMG01.JPG
|||IMG02.HEIC
|||IMG02.JPG
|||IMG03.HEIC
|||IMG03.JPG
And what I'm trying to accomplish is this:
Years
|2019
||09.01.19 - Visiting the Zoo
|||Photo1.JPG
|||Photo2.JPG
|||Photo3.JPG
|||09.01.19 - Visiting the Zoo(HEIC).7z
|2020
||09.02.20 - Pumpkin Picking
|||DSC01.JPG
|||DSC02.JPG
|||DSC03.JPG
|||09.02.20 - Pumpkin Picking(HEIC).7z
|2021
||09.04.21 - Whitewater Rafting
|||IMG01.JPG
|||IMG02.JPG
|||IMG03.JPG
|||09.04.21 - Whitewater Rafting(HEIC).7z
Here is the script I have so far:
$7zipPath = "$env:ProgramFiles\7-Zip\7z.exe"
if (-not (Test-Path -Path $7zipPath -PathType Leaf)) {
throw "7 zip file '$7zipPath' not found"
}
Set-Alias 7zip $7zipPath
$path = "T:\TEST\YEARS"
$dest = "T:\TEST\YEARS"
$mask = "*.HEIC"
$files = dir $path -Recurse -Include $mask
ForEach ($file in $files)
{
7zip a tzip mx "$dest\$($file.basename)HEIC.7z" $file
}
Get-ChildItem -Path 'T:\TEST\YEARS' $mask -Recurse | foreach { Remove-Item -Path $_.FullName }
The problem with the above script is that it moves the zipped files to "T:\TEST\YEARS" and doesn't leave it in the subfolder. In addition it adds every subfolder together.
With the zipping not working, I've not yet tested the deletion of the HEIC files.
How do I fix this issue?
Thanks!
EDIT: After consulting on another forum, here is the script I wound up using:
$yearDir = "$PSScriptRoot\YEARS" #changes this.
try {
$yearDirResults = Get-ChildItem -Path $yearDir -Directory -ErrorAction Stop
}
catch {
Write-Error $Error[0] -ErrorAction Stop
}
#could've done a another foreach-object for $yearDirResults but thought this would be easier to read..
foreach ($year in $yearDirResults) {
$compressError = $false #we use this later, make sure it's false for now.
try {
#For each 'YEAR' folder (i.e. 2019,2020,2021); get all child-items, no recurse, and create archive of HEIC files..
Get-ChildItem -Path $year.FullName -Directory -ErrorAction Stop | ForEach-Object {
#for each sub-directory of "YEAR" (i.e. '2021\whitewater rafting')
$heicFiles = Test-Path "$($_.FullName)\*" -Include '*.heic' #a simple test to see if our current directory has any HEIC files.
if ($heicFiles) {
#looks like we have HEIC files so let's do archive/compression stuff...
$compressionPath = "$($_.FullName)\*.HEIC" #Compress-Archive uses this for the -Path param of all files to compress. We can use a wildcard of *.heic.
$zipName = "$(Split-Path $($_.FullName) -Leaf)(HEIC).zip" # do some string stuff to get the ZIP output file name based on the current directory we're working with.
$heicZipOutput = Join-Path -Path $($_.FullName) -ChildPath $zipName # join the main folder name along with the zip name to get a full path for DestinationPath param on Compress-Archive.
"Compressiong $compressionPath and outputting to $heicZipOutput"
try {
#we don't want to delete our HEIC files unless we know Compress-Archvie completed without error so we put it in a try/catch block.
#For Compress-Archive I'm using -Update parameter instead of -Force. Using -Force will overwrite a .zip file with the same name if one already exists.
#I think "Update" is a better choice over "Force" because if you ever add any new HEIC files to a directory that already contains a .zip archive then the archive will be updated with new files instead of deleted and only contain the new files.
Compress-Archive -Path $compressionPath -DestinationPath $heicZipOutput -Update -CompressionLevel Fastest -ErrorAction Stop #-WhatIf #uncomment the -WhatIf to see what would happen if this was actually run.
}
catch {
$compressError = $true
Write-Error $Error[0]
}
if($compressError){
#Well, there was an error creating the .zip archive so we through a warning and move on..
Write-Warning "There was an error creating our archive in $heicZipOutput. Not deleting any files."
} else {
Write-Warning "Deleting HEIC files from $($_.FullName)"
try {
Remove-Item -Path "$($_.FullName)\*" -Include '*.heic' -ErrorAction Stop -Force -WhatIf #Remove -WhatIf when ready to actually delete files.
}
catch {
#Unable to remove HEIC files from a folder is an error only for this specific loop case - we use continue to move to next iteration.
Write-Error $Error[0] -ErrorAction Continue
}
}
}
else {
#Well, looks like $heicFiles was empty (no HEIC files found in current dir) so we just spit out a warning and move on.
Write-Warning "No HEIC files found in $($_.FullName). Skipping compression."
}
}
}
catch {
#hopefully we'd never end up here but simple error catching in case Get-ChildItem filed on $year.FullName.
Write-Error $Error[0] -ErrorAction Stop
}
}
After checking with another forum here is the script I wound up using:
$yearDir = "$PSScriptRoot\YEARS" #changes this.
try {
$yearDirResults = Get-ChildItem -Path $yearDir -Directory -ErrorAction Stop
}
catch {
Write-Error $Error[0] -ErrorAction Stop
}
#could've done a another foreach-object for $yearDirResults but thought this would be easier to read..
foreach ($year in $yearDirResults) {
$compressError = $false #we use this later, make sure it's false for now.
try {
#For each 'YEAR' folder (i.e. 2019,2020,2021); get all child-items, no recurse, and create archive of HEIC files..
Get-ChildItem -Path $year.FullName -Directory -ErrorAction Stop | ForEach-Object {
#for each sub-directory of "YEAR" (i.e. '2021\whitewater rafting')
$heicFiles = Test-Path "$($_.FullName)\*" -Include '*.heic' #a simple test to see if our current directory has any HEIC files.
if ($heicFiles) {
#looks like we have HEIC files so let's do archive/compression stuff...
$compressionPath = "$($_.FullName)\*.HEIC" #Compress-Archive uses this for the -Path param of all files to compress. We can use a wildcard of *.heic.
$zipName = "$(Split-Path $($_.FullName) -Leaf)(HEIC).zip" # do some string stuff to get the ZIP output file name based on the current directory we're working with.
$heicZipOutput = Join-Path -Path $($_.FullName) -ChildPath $zipName # join the main folder name along with the zip name to get a full path for DestinationPath param on Compress-Archive.
"Compressiong $compressionPath and outputting to $heicZipOutput"
try {
#we don't want to delete our HEIC files unless we know Compress-Archvie completed without error so we put it in a try/catch block.
#For Compress-Archive I'm using -Update parameter instead of -Force. Using -Force will overwrite a .zip file with the same name if one already exists.
#I think "Update" is a better choice over "Force" because if you ever add any new HEIC files to a directory that already contains a .zip archive then the archive will be updated with new files instead of deleted and only contain the new files.
Compress-Archive -Path $compressionPath -DestinationPath $heicZipOutput -Update -CompressionLevel Fastest -ErrorAction Stop #-WhatIf #uncomment the -WhatIf to see what would happen if this was actually run.
}
catch {
$compressError = $true
Write-Error $Error[0]
}
if($compressError){
#Well, there was an error creating the .zip archive so we through a warning and move on..
Write-Warning "There was an error creating our archive in $heicZipOutput. Not deleting any files."
} else {
Write-Warning "Deleting HEIC files from $($_.FullName)"
try {
Remove-Item -Path "$($_.FullName)\*" -Include '*.heic' -ErrorAction Stop -Force -WhatIf #Remove -WhatIf when ready to actually delete files.
}
catch {
#Unable to remove HEIC files from a folder is an error only for this specific loop case - we use continue to move to next iteration.
Write-Error $Error[0] -ErrorAction Continue
}
}
}
else {
#Well, looks like $heicFiles was empty (no HEIC files found in current dir) so we just spit out a warning and move on.
Write-Warning "No HEIC files found in $($_.FullName). Skipping compression."
}
}
}
catch {
#hopefully we'd never end up here but simple error catching in case Get-ChildItem filed on $year.FullName.
Write-Error $Error[0] -ErrorAction Stop
}
}
A BIG THANK YOU to everyone who helped me with this. Even if I didn't use your solution I still appreciate your time and effort.