Anavem
Languagefr
How to Clean Up Exchange Server Logs Using PowerShell to Free Disk Space

How to Clean Up Exchange Server Logs Using PowerShell to Free Disk Space

Create and run PowerShell scripts to automatically clean up log files from Exchange 2013, 2016, and 2019 servers, freeing valuable disk space by safely removing old IIS, ETL, and Exchange logs.

April 13, 2026 15 min
mediumexchange-server 8 steps 15 min

Why Clean Up Exchange Server Logs Regularly?

Exchange Server generates massive amounts of log data during normal operation. IIS logs, Exchange protocol logs, ETL diagnostic files, and search indexing logs can quickly consume hundreds of gigabytes of disk space. Without regular maintenance, these logs can fill up your server drives, causing Exchange services to fail and potentially bringing down email services for your entire organization.

What Types of Logs Does Exchange Generate?

Exchange servers create several categories of logs that require cleanup. IIS logs track web requests to Exchange web services and can grow to several gigabytes per day in busy environments. Exchange protocol logs monitor MAPI, EWS, and ActiveSync connections, while ETL (Event Trace Log) files capture diagnostic information for troubleshooting. Search indexing logs from the Content Index service also accumulate over time, especially in environments with large mailbox databases.

How Does PowerShell Automation Help with Log Management?

Manual log cleanup is time-consuming and error-prone. PowerShell automation allows you to create intelligent scripts that identify old log files based on age, safely delete them while preserving recent data needed for troubleshooting, and run on a schedule to maintain optimal disk space usage. The scripts can also provide detailed reporting on space freed and integrate with monitoring systems to alert administrators when cleanup operations complete or encounter issues.

Implementation Guide

Full Procedure

01

Configure PowerShell Execution Policy

Before running any PowerShell scripts, you need to configure the execution policy to allow script execution. By default, Windows servers restrict PowerShell script execution for security reasons.

Open PowerShell as Administrator and run the following command:

Set-ExecutionPolicy RemoteSigned -Force

This allows locally created scripts and signed remote scripts to run. The -Force parameter bypasses confirmation prompts.

Verification: Check the current execution policy:

Get-ExecutionPolicy

You should see RemoteSigned as the output.

Pro tip: If you're running scripts through Task Scheduler, you can bypass execution policy restrictions by using -ExecutionPolicy Bypass in the scheduled task command.
02

Create the Log Cleanup Script Directory

Create a dedicated directory for your cleanup scripts. This keeps your scripts organized and makes scheduling easier.

New-Item -Path "C:\Scripts" -ItemType Directory -Force

Navigate to the scripts directory:

Set-Location "C:\Scripts"

Verification: Confirm the directory was created:

Test-Path "C:\Scripts"

This should return True.

Warning: Ensure the service account you'll use for scheduling has full control permissions on this directory.
03

Download and Prepare the Exchange Log Cleanup Script

Since Microsoft doesn't provide an official log cleanup script, we'll use the community-maintained SammyKrosoft script from GitHub, which is compatible with Exchange 2013, 2016, and 2019.

Download the script using PowerShell:

Invoke-WebRequest -Uri "https://raw.githubusercontent.com/SammyKrosoft/Clean-Exchange-Log-Files/master/CleanExchangeLogFiles.ps1" -OutFile "C:\Scripts\CleanExchangeLogFiles.ps1"

Alternatively, create your own simplified version. Save this as C:\Scripts\CleanupExchangeLogs.ps1:

# Exchange Log Cleanup Script
param(
    [int]$Days = 7,
    [switch]$DoNotDelete
)

$LogPaths = @(
    "$env:SystemDrive\inetpub\logs\LogFiles",
    "$env:ExchangeInstallPath\Logging",
    "$env:ExchangeInstallPath\Bin\Search\Ceres\Diagnostics\Logs"
)

$CutoffDate = (Get-Date).AddDays(-$Days)
$TotalSize = 0

foreach ($Path in $LogPaths) {
    if (Test-Path $Path) {
        $Files = Get-ChildItem -Path $Path -Recurse -File | Where-Object {$_.LastWriteTime -lt $CutoffDate}
        $PathSize = ($Files | Measure-Object -Property Length -Sum).Sum
        $TotalSize += $PathSize
        
        Write-Host "Found $($Files.Count) files in $Path ($('{0:N2}' -f ($PathSize/1MB)) MB)"
        
        if (-not $DoNotDelete) {
            $Files | Remove-Item -Force -ErrorAction SilentlyContinue
            Write-Host "Deleted files older than $Days days from $Path"
        }
    }
}

Write-Host "Total space that would be freed: $('{0:N2}' -f ($TotalSize/1MB)) MB"

Verification: Check that the script file exists:

Get-ChildItem "C:\Scripts\*.ps1"
04

Test the Script with Dry Run

Before actually deleting files, run the script in test mode to see what files would be removed and how much space would be freed.

Run the dry run command:

C:\Scripts\CleanupExchangeLogs.ps1 -Days 7 -DoNotDelete

This will scan for log files older than 7 days without deleting them. You'll see output similar to:

Found 245 files in C:\inetpub\logs\LogFiles (156.23 MB)
Found 89 files in C:\Program Files\Microsoft\Exchange Server\V15\Logging (89.45 MB)
Total space that would be freed: 245.68 MB

Review the output carefully. If you see critical system files or recent logs being targeted, adjust the -Days parameter.

Verification: Check that no files were actually deleted by running the same command again - the numbers should be identical.

Pro tip: Start with a conservative retention period like 7-14 days for your first cleanup, then adjust based on your organization's compliance requirements.
05

Execute the Log Cleanup

Once you're satisfied with the dry run results, execute the actual cleanup. Start with a shorter retention period to be safe.

Run the cleanup for files older than 7 days:

C:\Scripts\CleanupExchangeLogs.ps1 -Days 7

The script will delete the identified files and show progress. You should see output confirming the deletions:

Deleted files older than 7 days from C:\inetpub\logs\LogFiles
Deleted files older than 7 days from C:\Program Files\Microsoft\Exchange Server\V15\Logging
Total space that would be freed: 245.68 MB

For more aggressive cleanup (use with caution), you can reduce the retention period:

C:\Scripts\CleanupExchangeLogs.ps1 -Days 2

Verification: Check the available disk space before and after:

Get-Volume C | Select-Object DriveLetter, SizeRemaining
Warning: Never set the retention period below 1 day, as this could delete logs needed for troubleshooting current issues. Some compliance requirements mandate longer retention periods.
06

Create a Service Account for Scheduled Cleanup

For automated cleanup, create a dedicated service account with the necessary permissions. This follows security best practices by not using administrator accounts for scheduled tasks.

Create the service account using PowerShell:

$SecurePassword = ConvertTo-SecureString "ComplexPassword123!" -AsPlainText -Force
New-LocalUser -Name "svc-ExchangeCleanup" -Password $SecurePassword -Description "Exchange Log Cleanup Service Account" -PasswordNeverExpires

Add the account to the local "Log on as a service" right and grant permissions to the log directories:

# Grant permissions to log directories
$LogPaths = @(
    "$env:SystemDrive\inetpub\logs\LogFiles",
    "$env:ExchangeInstallPath\Logging",
    "C:\Scripts"
)

foreach ($Path in $LogPaths) {
    if (Test-Path $Path) {
        $Acl = Get-Acl $Path
        $AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("svc-ExchangeCleanup", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow")
        $Acl.SetAccessRule($AccessRule)
        Set-Acl $Path $Acl
        Write-Host "Granted permissions to $Path"
    }
}

Verification: Test the service account by running the script as that user:

Start-Process powershell -Credential (Get-Credential svc-ExchangeCleanup) -ArgumentList "-File C:\Scripts\CleanupExchangeLogs.ps1 -Days 7 -DoNotDelete"
07

Schedule Automated Log Cleanup

Create a scheduled task to run the cleanup script automatically. This ensures consistent maintenance without manual intervention.

Create the scheduled task using PowerShell:

$TaskName = "Exchange Log Cleanup"
$ScriptPath = "C:\Scripts\CleanupExchangeLogs.ps1"
$TaskAction = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-ExecutionPolicy Bypass -File `"$ScriptPath`" -Days 7"
$TaskTrigger = New-ScheduledTaskTrigger -Daily -At "2:00 AM"
$TaskSettings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable
$TaskPrincipal = New-ScheduledTaskPrincipal -UserId "svc-ExchangeCleanup" -LogonType ServiceAccount

Register-ScheduledTask -TaskName $TaskName -Action $TaskAction -Trigger $TaskTrigger -Settings $TaskSettings -Principal $TaskPrincipal -Description "Daily cleanup of Exchange Server log files"

Alternatively, create the task through Task Scheduler GUI:

1. Open Task Scheduler (taskschd.msc)
2. Create Basic Task → Name: "Exchange Log Cleanup"
3. Trigger: Daily at 2:00 AM
4. Action: Start a program
5. Program: powershell.exe
6. Arguments: -ExecutionPolicy Bypass -File "C:\Scripts\CleanupExchangeLogs.ps1" -Days 7
7. Run as: svc-ExchangeCleanup

Verification: Test the scheduled task:

Start-ScheduledTask -TaskName "Exchange Log Cleanup"
Get-ScheduledTask -TaskName "Exchange Log Cleanup" | Get-ScheduledTaskInfo
Pro tip: Schedule the cleanup during off-hours (2-4 AM) to minimize impact on Exchange performance, and consider running it on weekends for heavy cleanup operations.
08

Monitor and Verify Cleanup Results

Set up monitoring to ensure your cleanup script is working effectively and not causing issues.

Create a simple monitoring script to track disk space trends. Save as C:\Scripts\MonitorDiskSpace.ps1:

# Disk Space Monitoring Script
$LogFile = "C:\Scripts\DiskSpaceLog.txt"
$Volume = Get-Volume C
$Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$FreeSpaceGB = [math]::Round($Volume.SizeRemaining / 1GB, 2)
$UsedSpacePercent = [math]::Round((($Volume.Size - $Volume.SizeRemaining) / $Volume.Size) * 100, 2)

$LogEntry = "$Timestamp - Free Space: $FreeSpaceGB GB ($UsedSpacePercent% used)"
Add-Content -Path $LogFile -Value $LogEntry

# Alert if disk usage exceeds 85%
if ($UsedSpacePercent -gt 85) {
    Write-EventLog -LogName Application -Source "Exchange Cleanup" -EventId 1001 -EntryType Warning -Message "Disk usage is $UsedSpacePercent% - cleanup may need adjustment"
}

Check the Windows Event Log for cleanup activities:

Get-WinEvent -FilterHashtable @{LogName='Application'; StartTime=(Get-Date).AddDays(-1)} | Where-Object {$_.LevelDisplayName -eq 'Information' -and $_.Message -like '*Exchange*'}

Review the scheduled task history:

Get-ScheduledTask -TaskName "Exchange Log Cleanup" | Get-ScheduledTaskInfo

Verification: Check that log files are being cleaned up regularly:

# Check oldest files in log directories
$LogPaths = @("$env:SystemDrive\inetpub\logs\LogFiles", "$env:ExchangeInstallPath\Logging")
foreach ($Path in $LogPaths) {
    if (Test-Path $Path) {
        $OldestFile = Get-ChildItem -Path $Path -Recurse -File | Sort-Object LastWriteTime | Select-Object -First 1
        Write-Host "Oldest file in $Path`: $($OldestFile.LastWriteTime) - $($OldestFile.Name)"
    }
}
Warning: If you notice Exchange services becoming unstable after cleanup, check that you haven't deleted active transaction logs. Transaction logs should be truncated through proper backup procedures, not file deletion.

Frequently Asked Questions

How often should I run Exchange Server log cleanup scripts?+
Run cleanup scripts daily during off-hours (2-4 AM) to maintain optimal disk space. For high-volume environments, consider twice-daily cleanup. Always retain logs for at least 7 days for troubleshooting, and longer if required by compliance policies. Monitor disk usage trends to adjust frequency as needed.
What's the difference between Exchange transaction logs and diagnostic logs?+
Transaction logs (.log files) contain database changes and should only be truncated through proper backup procedures, never deleted manually. Diagnostic logs (IIS, ETL, protocol logs) are safe to delete after retention periods and don't affect database integrity. PowerShell cleanup scripts target diagnostic logs only.
Can I run log cleanup scripts on Exchange 2019 in 2026?+
Yes, Exchange 2019 CU15 (latest as of 2026) fully supports PowerShell log cleanup scripts. The community scripts from GitHub work with Exchange 2013, 2016, and 2019 using environment variables to detect installation paths. Ensure you're using the latest script versions for compatibility.
What permissions does the service account need for automated cleanup?+
The service account needs Read/Write permissions on log directories including C:\inetpub\logs\LogFiles, %ExchangeInstallPath%\Logging, and search diagnostic folders. Grant 'Log on as a service' rights and Full Control NTFS permissions on these paths. Avoid using administrator accounts for scheduled tasks.
How do I troubleshoot PowerShell execution policy errors?+
Set execution policy to RemoteSigned using 'Set-ExecutionPolicy RemoteSigned -Force' as Administrator. For scheduled tasks, use '-ExecutionPolicy Bypass' parameter to override restrictions. If Group Policy blocks changes, work with your domain administrators to allow script execution on Exchange servers.

Discussion

Share your thoughts and insights

Sign in to join the discussion