This is a progression of the script I posted here: Zip the contents of subfolders, conditionally
It does this:
Determines all subfolders recursively
Checks each subfolder for files older than 31 days which aren't .zip
If such files found, creates a new folder within, labelled with the date
Moves the files to the new folder
Creates a zipped copy of the new folder
Deletes the new folder and its contents
There's error-handling and logging built-in
#Run under Powershell v1 or v2
#Pass the target log folder as a parameter: '-LogFolder Path\to\logfolder'
param(
[parameter(Mandatory=$true)]
[ValidateScript({
if (Test-Path $_ -PathType Container) {$true}
else {Throw "Folder $_ not found"}})]
[String]
$LogFolder
)
#Get working directory, for outputting log file
$WorkingDirectory = (pwd).path
#Print datestamp to the log file
Get-date >> "$WorkingDirectory\OutputLog.txt"
"Log directory: $LogFolder" >> "$WorkingDirectory\OutputLog.txt"
#Record total size of the target log folder before compression
$Logsize = Get-ChildItem -recurse $LogFolder | Measure-Object -property length -sum
$MBsize = "{0:N2}" -f ($Logsize.sum / 1MB) + " MB"
"Initial Log folder size: $MBsize" >> "$WorkingDirectory\OutputLog.txt"
#Verify that the Zip.dll is present
$testzip = Test-Path .\ICSharpCode.SharpZipLib.dll
#If the Zip.dll is found, bind it to a variable and load it, otherwise exit
#In other words, if the script cannot load the Zip module, it will do nothing
if ($testzip -eq $True){
$ZipModule = Get-ChildItem .\ICSharpCode.SharpZipLib.dll | Select -ExpandProperty FullName
[void][System.Reflection.Assembly]::LoadFrom($ZipModule)
}
Else{
"Zip dll not found or couldn't be loaded.
Check file is present and unblocked.
Exiting" >> "$WorkingDirectory\OutputLog.txt"
Exit
}
#Get all subfolders
$subfolders = Get-ChildItem $LogFolder -Recurse |
Where-Object { $_.PSIsContainer -and $_.fullname -notmatch "\\jsonTemplates\\verifier\\?" }
ForEach ($s in $subfolders) {
$path = $s #$s variable contains each folder
$path
Set-Location $path.FullName
$fullpath = $path.FullName
#Get all items older than 31 days, exclude zip files and folders
$items = Get-ChildItem -Exclude *.zip |
Where-Object {$_.LastWriteTime -lt (Get-date).AddDays(-31)
-and -not $_.psIsContainer}
#Verify that there are such items in this directory, catch errors
if ( $(Try { Test-Path $items }
Catch { "Cannot find items in $fullpath.
Sub-folders will be processed afterwards.
ERROR: $_" >> "$WorkingDirectory\OutputLog.txt" }) ) {
$date = Get-Date -Format 'yyyy-MM-dd_HH-mm'
$newpath = "$path-$date"
$newpath
$newfld = New-Item -ItemType Directory -name $newpath
$src = $newfld.FullName
#move items to newly-created folder
Move-Item $items -destination $src
$dest = "$src.zip"
"Compressing $src to $dest" >> "$WorkingDirectory\OutputLog.txt"
#the following block zips the folder
try{
$zip = New-Object ICSharpCode.SharpZipLib.Zip.FastZip
$zip.CreateZip($dest, $src, $true, ".*")
Remove-Item $src -force -recurse
}
catch {
"Folder could not be compressed. Removal of $src ABORTED.
ERROR: $_" >> "$WorkingDirectory/OutputLog.txt"
}
}
}
#Record total size of the target log folder after compression
$Logsize = Get-ChildItem -recurse $LogFolder | Measure-Object -property length -sum
$MBsize = "{0:N2}" -f ($Logsize.sum / 1MB) + " MB"
"Final Log folder size: $MBsize" >> "$WorkingDirectory\OutputLog.txt"
Set-Location $LogFolder