Private/Backup-LogFile.ps1

function Backup-LogFile {
    <#
    .SYNOPSIS
        Rotates the log file if its age exceeds the configured threshold.
 
    .DESCRIPTION
        Checks the age of the current log file (referenced via $script:LogFilePath). If the file
        is older than MaxLogAgeDays, it is moved to a date-stamped backup and a new empty log is
        created. A maximum of 3 rolling backups is maintained; the oldest is deleted before a new
        backup is written when the count reaches the limit.
 
        Backup naming convention: <BaseName>_<yyyy-MM>.log
        Example: ApplicationStartup_2026-01.log
 
        If the log file does not exist, it is created and the function returns early.
 
    .PARAMETER MaxLogAgeDays
        The maximum age in days before the log file is rotated. Defaults to 30.
 
    .NOTES
        Author: Aaron AlAnsari
        Created: 2026-02-24
 
        Rolling backup behavior (max 3 backups):
          Rotation 1 → backup 1 exists
          Rotation 2 → backups 1–2 exist
          Rotation 3 → backups 1–3 exist
          Rotation 4+ → oldest deleted, new backup written, still 3 backups
    #>


    [CmdletBinding()]
    [OutputType([void])]
    param (
        [Parameter()]
        [int]$MaxLogAgeDays = 30
    )

    $logDir  = Split-Path -Path $script:LogFilePath -Parent
    $logBase = [System.IO.Path]::GetFileNameWithoutExtension($script:LogFilePath)

    # Ensure the log directory exists.
    if (-not (Test-Path -Path $logDir)) {
        New-Item -ItemType Directory -Path $logDir -Force | Out-Null
    }

    # Guard: if the log file does not exist, create it and return.
    if (-not (Test-Path -Path $script:LogFilePath)) {
        New-Item -Path $script:LogFilePath -ItemType File -Force | Out-Null
        return
    }

    # Check the age of the current log file.
    $logFileInfo  = Get-Item -Path $script:LogFilePath
    $logAgeDays   = ((Get-Date) - $logFileInfo.LastWriteTime).Days

    if ($logAgeDays -lt $MaxLogAgeDays) {
        return
    }

    # Build date-stamped backup filename (yyyy-MM of last write time).
    $dateSuffix  = $logFileInfo.LastWriteTime.ToString('yyyy-MM')
    $backupName  = "${logBase}_${dateSuffix}.log"
    $backupPath  = Join-Path $logDir $backupName

    # Enforce rolling backup limit: delete the oldest if at or above 3 backups.
    $maxBackups  = 3
    $existing    = @(Get-ChildItem -Path $logDir -Filter "${logBase}_*.log" | Sort-Object LastWriteTime)
    if ($existing.Count -ge $maxBackups) {
        Remove-Item -Path $existing[0].FullName -Force
    }

    # Rotate: move current log to backup, create new empty log.
    Move-Item -Path $script:LogFilePath -Destination $backupPath -Force
    New-Item -Path $script:LogFilePath -ItemType File -Force | Out-Null
}