function Backup-LogFiles { <# .SYNOPSIS Saves old logs into an Archive subfolder. #> [CmdletBinding()] Param( [Parameter(Mandatory = $false)] [Alias("LogPath")] [string]$logDirectory, [Parameter(Mandatory = $false)] [Alias("CutoffDays")] [int]$archiveOlderThanDays = 0, [Parameter(Mandatory = $false)] [string]$filter = "*.log*" ) $logLead = (Get-LogLeadName) if ([string]::IsNullOrEmpty($logDirectory)) { $logDirectory = (Get-OrbLogsPath) } if (!(Test-Path $logDirectory)) { Write-Warning "$logLead : Directory `"$logDirectory`" not found. Skipping."; return; } $archivePath = Join-Path $logDirectory "Archive"; Write-Host "$logLead : Backing up / Archiving logs in `"$logdirectory`""; if (!(Test-Path $archivePath)) { New-Item $archivePath -ItemType Directory | Out-Null; } # Determine the cutoff date to archive files. $absoluteCutoff = [System.Math]::Abs($archiveOlderThanDays); $cutoffDate = (Get-Date).AddDays($absoluteCutoff * -1); $cutoffUtc = [System.TimeZoneInfo]::ConvertTimeToUtc($cutoffDate); # Remove any potential trailing wildcarded directories while ($logDirectory.Substring($logDirectory.get_length() - 2) -eq "\*" ) { Write-Host "Found a wildcard. Trimming..." $logDirectory = $logDirectory.Substring(0, $logDirectory.get_length() - 2) } # Tack on a single \* so that Get-ChildItem plays nicely with both the exclude and filter parameters $logDirectory = $logDirectory + "\*" # Figure out which files need to be archived. $logFiles = Get-ChildItem $logDirectory -Exclude *.zip, *.7z -Filter $filter -File | Where-Object { $_.LastWriteTimeUtc -lt $cutoffUtc } # Archive each file. $szPath = (Get-7ZipPath) foreach ($file in $logFiles) { Write-Verbose "Archiving $($file.FullName)"; $archiveZip = $file.LastWriteTimeUtc.ToString("yyyy-MM-dd"); $archiveZip = "$archiveZip.zip" $archiveZip = Join-Path $archivePath $archiveZip $archiveExists = Test-Path $archiveZip; # Figure out if the file is already in the zip. # We have to rename a file, and then add it, to prevent the original file in the zip from being overwritten. # This is particularly an issue if we do multiple deploys inside a day, which would overwrite the active log. $fileToArchive = $file.FullName; $tempPath = $null; try { if ($archiveExists) { # Search files inside the archive. $archiveFiles = (& $szPath l -r $archiveZip) | Where-Object { $_ -like "*$file*" -or $_ -like "*$($file.BaseName)_*$($file.Extension)" } $fileCount = $archiveFiles.count; if ($fileCount -gt 0) { Write-Verbose "File name $($file.Name) already exists in the archive `"$archiveZip`" Creating a temporary log file copy & adding it to the archive."; # Turns "C:/some/base/path/logname.log" into "C:/some/base/path/logname_2.log" $tempFileName = "$($file.BaseName)_$fileCount$($file.Extension)" $tempPath = Join-Path $file.Directory $tempFileName; Copy-Item -Path $file.FullName -Destination $tempPath $fileToArchive = $tempPath; } } try { & $szPath a -tzip -sdel -y $archiveZip $fileToArchive; } catch { Write-Warning $_.Exception; } # Clean up the original file if there was a pre-existing file in the archive. # 7-Zip removes a file when it adds it to an archive. if ($tempPath -and (Test-Path $file.FullName)) { Write-Verbose "Removing log $($file.FullName) because it was a duplicate filename in the `"$archiveZip`" archive." Remove-Item -Path $file.FullName -Force; } } catch { Write-Warning $_.Exception; } finally { # Remove temporary log files if zipping failed out for any reason. if ($tempPath -and (Test-Path $tempPath)) { Write-Verbose "Removing temporary log file copy `"$tempPath`""; Remove-Item -Path $tempPath -Force; } } } Write-Host "$logLead : Backup complete."; }