ps/Modules/Alkami.PowerShell.Common/Public/Backup-LogFiles.ps1
2023-05-30 22:51:22 -07:00

115 lines
4.4 KiB
PowerShell

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.";
}