Exchange Server Log Cleanup
PowerShell script to clean up IIS, Exchange (General, ETL, Diagnostic) logs older than a specified retention period. Supports selective log types and optional logging to a designated folder.
.\ExchangeLogCleanup.ps1 -LogFolder C:\ExchangeLogCleanup\Logs -TargetLogs IIS,ETL -RetentionDays 7 -LogRetentionDays 7
Cleans IIS and ETL logs older than 14 days. Logs are saved to the specified folder, and old script logs older than 14 days are also removed.
.\ExchangeLogCleanup.ps1 -LogFolder C:\ExchangeLogCleanup\Logs -RetentionDays 30 -LogRetentionDays 30
Cleans all supported log types older than 30 days. Logs the cleanup process and removes script logs older than 30 days from the log folder.
<#
.SYNOPSIS
WARNING: This script deletes IIS and Exchange log files and should be used with caution.
Use only if you understand the implications of deleting log files.
I take no responsibility for data loss caused by this script.
.DESCRIPTION
This script cleans IIS, Exchange General, ETL, and Diagnostic logs older than a defined retention period.
It also cleans its own log files older than a configurable retention period.
.PARAMETER RetentionDays
Defines the retention period for Exchange logs (default is 14 days).
.PARAMETER TargetLogs
Allows you to specify which logs to clean: IIS, ExchangeGeneral, ETL, Diagnostics, or All.
.PARAMETER LogFolder
Optional: Folder where cleanup logs are recorded.
- A timestamped log file will be created in that folder.
.PARAMETER LogRetentionDays
Retention period for the script’s own log files in the specified LogFolder (default is 30 days).
.EXAMPLE
.\ExchangeLogCleanup.ps1
Cleans all logs older than 14 days without logging.
.EXAMPLE
.\ExchangeLogCleanup.ps1 -RetentionDays 5 -TargetLogs IIS,ETL
Cleans only IIS and ETL logs older than 5 days.
.EXAMPLE
.\ExchangeLogCleanup.ps1 -LogFolder "C:\Logs" -LogRetentionDays 180
Cleans all logs older than 14 days, logs the process to "C:\Logs", and cleans log files older than 180 days.
.NOTES
Author: Universal Trust
Version: 1.4
Date: 12/11/2024
Compatibility: Exchange 2019/SE
#>
param (
[int]$RetentionDays = 14,
[ValidateSet("IIS", "ExchangeGeneral", "ETL", "Diagnostics", "All")]
[string[]]$TargetLogs = @("All"),
[string]$LogFolder,
[int]$LogRetentionDays = 30
)
# Initialize global counters
$Global:TotalFilesCleaned = 0
$Global:TotalSizeCleaned = 0
$Global:TotalFilesFailed = 0
# Prepare logging
if ($LogFolder) {
if (-not (Test-Path $LogFolder)) {
New-Item -Path $LogFolder -ItemType Directory | Out-Null
}
$Timestamp = Get-Date -Format "ddMMyy-HHmmss"
$LogFile = Join-Path -Path $LogFolder -ChildPath "ExchangeLogCleanup-$Timestamp.log"
}
# Define log directories
$ProgramFilesPath = $env:ProgramFiles
$LogDirectories = @{
"IIS" = "C:\inetpub\logs\LogFiles\"
"ExchangeGeneral" = "$ProgramFilesPath\Microsoft\Exchange Server\V15\Logging\"
"ETL" = "$ProgramFilesPath\Microsoft\Exchange Server\V15\Bin\Search\Ceres\Diagnostics\ETLTraces\"
"Diagnostics" = "$ProgramFilesPath\Microsoft\Exchange Server\V15\Bin\Search\Ceres\Diagnostics\Logs\"
}
# Logging function
function Write-Log {
param (
[string]$Message,
[string]$ForegroundColor = "White"
)
$Timestamp = (Get-Date -Format "dd-MM-yyyy HH:mm:ss")
$FormattedMessage = "$Timestamp - $Message"
Write-Host $FormattedMessage -ForegroundColor $ForegroundColor
if ($LogFile) {
Add-Content -Path $LogFile -Value $FormattedMessage
}
}
# Convert file size
function Convert-Size {
param ([int64]$Bytes)
switch ($Bytes) {
{ $_ -ge 1GB } { return "{0:N2} GB" -f ($Bytes / 1GB) }
{ $_ -ge 1MB } { return "{0:N2} MB" -f ($Bytes / 1MB) }
{ $_ -ge 1KB } { return "{0:N2} KB" -f ($Bytes / 1KB) }
default { return "$Bytes Bytes" }
}
}
# Cleanup function
function Clean-LogFiles {
param ($TargetFolder, $LogType, $DaysToKeep)
Write-Log "Processing $LogType logs in: $TargetFolder" -ForegroundColor Cyan
if (Test-Path $TargetFolder) {
$ThresholdDate = (Get-Date).AddDays(-$DaysToKeep)
$FilesToDelete = Get-ChildItem -Path $TargetFolder -Recurse -File -ErrorAction SilentlyContinue |
Where-Object { $_.LastWriteTime -lt $ThresholdDate }
foreach ($File in $FilesToDelete) {
try {
$FileSize = $File.Length
Remove-Item -Path $File.FullName -Force -ErrorAction Stop
$Global:TotalFilesCleaned++
$Global:TotalSizeCleaned += $FileSize
Write-Log "Deleted: $($File.FullName) (Filesize: $(Convert-Size -Bytes $FileSize))" -ForegroundColor Green
} catch {
$Global:TotalFilesFailed++
Write-Log "Failed to delete: $($File.FullName) (Error: $($_.Exception.Message))" -ForegroundColor Red
}
}
} else {
Write-Log "Directory not found: $TargetFolder" -ForegroundColor Red
}
}
# Cleanup script's own logs
function Clean-ScriptLogs {
if ($LogFolder) {
Write-Log "Cleaning script logs older than $LogRetentionDays days in: $LogFolder" -ForegroundColor Cyan
$ThresholdDate = (Get-Date).AddDays(-$LogRetentionDays)
$LogsToDelete = Get-ChildItem -Path $LogFolder -Recurse -File -Filter "*.log" -ErrorAction SilentlyContinue |
Where-Object { $_.LastWriteTime -lt $ThresholdDate }
foreach ($Log in $LogsToDelete) {
try {
Remove-Item -Path $Log.FullName -Force -ErrorAction Stop
Write-Log "Deleted old script log: $($Log.FullName)" -ForegroundColor Yellow
} catch {
Write-Log "Failed to delete script log: $($Log.FullName) (Error: $($_.Exception.Message))" -ForegroundColor Red
}
}
}
}
# Main execution
Write-Log "Starting Exchange log cleanup..." -ForegroundColor White
if ($TargetLogs -contains "All") {
foreach ($LogType in $LogDirectories.Keys) {
Clean-LogFiles -TargetFolder $LogDirectories[$LogType] -LogType $LogType -DaysToKeep $RetentionDays
}
} else {
foreach ($LogType in $TargetLogs) {
if ($LogDirectories.ContainsKey($LogType)) {
Clean-LogFiles -TargetFolder $LogDirectories[$LogType] -LogType $LogType -DaysToKeep $RetentionDays
} else {
Write-Log "Invalid log type specified: $LogType" -ForegroundColor Red
}
}
}
Clean-ScriptLogs
# Final summary
Write-Log "Summary: Total files cleaned: $Global:TotalFilesCleaned" -ForegroundColor Yellow
Write-Log "Summary: Total size cleaned: $(Convert-Size -Bytes $Global:TotalSizeCleaned)" -ForegroundColor Yellow
Write-Log "Summary: Total files failed to delete: $Global:TotalFilesFailed" -ForegroundColor Yellow
Write-Log "Exchange log cleanup completed!" -ForegroundColor Green
Last updated