PowerShell write-Log函数优化:日志归档与旧日志管理需求
PowerShell Log Function with Auto-Archiving
Alright, let's tackle this log rotation problem for your PowerShell script. Your current write-Log function appends to the log file, but you want to archive old logs to a subfolder with incrementing names while keeping the latest log in the script directory. Here's the revised solution with explanations:
Updated Code
First, set up your log variables and initialize a flag to prevent repeated archiving during the same script run:
# Log Variables $Logfile = "C:\Scripts\powershellscript\logs.log" # Main log file path # Initialize a script-level flag to track if we've already archived old logs in this session $script:logArchived = $false
Now here's the modified write-Log function with archiving logic:
function write-Log { Param ( [Parameter(Mandatory = $false)] # Message to log $Message, [Parameter(Mandatory = $false)] # Error message (triggers Type 3) $ErrorMessage, [Parameter(Mandatory = $false)] # Component generating the log entry $Component, [Parameter(Mandatory = $false)] # Log entry type (1=Info, 3=Error) [int]$Type, [Parameter(Mandatory = $true)] # Path to the main log file $LogFile ) # --- Auto-Archiving Logic (New) --- # Only run this once per script execution if (-not $script:logArchived) { # Derive the archive folder path from the main log's directory $archiveFolder = Join-Path -Path (Split-Path -Path $LogFile -Parent) -ChildPath "logfolder" # Create the archive folder if it doesn't exist if (-not (Test-Path -Path $archiveFolder)) { New-Item -ItemType Directory -Path $archiveFolder | Out-Null } # If the main log file exists (from a previous script run), archive it if (Test-Path -Path $LogFile) { # Get all existing archived logs to find the next increment number $existingArchives = Get-ChildItem -Path $archiveFolder -Filter "logs*.log.old" | Sort-Object Name -Descending $nextArchiveNumber = 1 # Extract the highest existing number to increment if ($existingArchives.Count -gt 0) { $latestArchive = $existingArchives[0].Name if ($latestArchive -match 'logs(\d+)\.log\.old') { $nextArchiveNumber = [int]$matches[1] + 1 } } # Define the path for the new archived log $archivedLogPath = Join-Path -Path $archiveFolder -ChildPath "logs$nextArchiveNumber.log.old" # Move and rename the old log file Move-Item -Path $LogFile -Destination $archivedLogPath -Force } # Mark archiving as complete for this script session $script:logArchived = $true } # --- Original Log Writing Logic (Unchanged) --- # Create timestamp for the log entry $Date = Get-Date -Format "MM/dd/yyyy" $time = Get-Date -Format "HH:mm:ss.fff" # Auto-set type to Error if an ErrorMessage is provided if ($null -ne $ErrorMessage) { $Type = 3 } # Default component to empty space if not specified if ($null -eq $Component) { $Component = " " } # Default type to Info if not specified if ($null -eq $Type) { $Type = 1 } # Build the log entry in the existing format $LogMessage = "<![LOG[$Message $ErrorMessage ]LOG]!>" + "<time=`"$time`" date=`"$Date`" component=`"$Component`" context=`"`" type=`"$Type`" thread=`"`" file=`">" # Append the entry to the main log file $LogMessage | Out-File -Append -Encoding UTF8 -FilePath $LogFile }
Key Improvements Explained
- Single-Run Archiving: The
$script:logArchivedflag ensures old logs are only archived once per script execution. This prevents repeatedly moving the current log file every time you callwrite-Log. - Dynamic Archive Path: The archive folder (
logfolder) is automatically created in the same directory as your main log file, so you don't need to hardcode paths. - Incrementing Naming: The function scans existing archived logs, extracts the highest number, and increments it for the new archive (e.g.,
logs1.log.old→logs2.log.old). - Backward Compatibility: All your existing calls to
write-Logwill work exactly as before—no need to modify how you pass parameters.
How It Works
- When you first call
write-Login your script, it checks if the main log file exists (from a prior run). - If it exists, it finds the next available increment number for archived logs.
- It moves the old log to
logfolderwith the incremented name. - It then proceeds to write new log entries to the fresh main log file.
- Subsequent calls to
write-Logduring the same script run skip the archiving step and just append to the current log.
内容的提问来源于stack exchange,提问作者StackLad
相关产品推荐
相关产品推荐

