There is a lot of focus on the Exchange Server Database, EDB, and transactional logs. But there are other logs we need to keep our eyes on. The services log was generated from Exchange Server 2016/2019 and IIS service logs. Cleanup these logs is also an important part of Exchange maintenance as these logs grow rapidly fast and consume a huge number of GB.
For this issue, I wrote a PowerShell script that will clean up IIS and Exchange Server Services Logs and ETL, which and over time consume much space.
Table of Contents
Downloading the Script
You can download the script from GitHub, feel free to report issues and contribute there.
Click here to go to the download page
Update on 22-Feb-2022
- Performance Monitor File .BLG files extension are also included in the files subject for removal. So the overall extensions are *.BLG, Log, ETL.
- Minor fixes
Prerequisites
- Windows PowerShell 5.1
- The Script should run on Exchange Server
- Exchange Snapin and WebAdministration. By default, these two modules are already available on Exchange Server.
- The Script should run as Administrator.
Cleanup Exchange Logs script, Features, and Parameters.
The script can auto-discovers Exchange Services log paths and IIS Log paths. In other words, no need to change anything in the script. Also, the script has the following features and parameters:
- JustCalculate: Get a summary of the total storage consumed by services logs (Exchange and IIS).
- SimulateDeleteLogs: Simulate Deletion, which writes a log that lists all files subject to removal.
- LogsOlderXDays: Only cleanup logs that are older than X number of days.
- DeleteLogs: Delete the old logs and free disk space.
- ExtraFolderToAdd: Include additional folders, such as Temp or any other folders for cleaning during the cleanup process (.Logs and .ETL files only).
There is no need to set Exchange Server in Maintenance mode, but if you need to, you can use my Exchange Maintenance Mode PowerShell module to handle all the steps safely and efficiently.
Examples
Using JustCalculate Parameter
Display a size summary of the total logs in each folder, this is the default parameter, so if PowerShell called the script without any parameter, it would trigger the JustCalculate
parameter.
.\Clean-ExchangeLogFiles.ps1 -JustCalculate
Using SimulateDeleteLogs
Parameter
The SimulateDeleteLogs
writes to a log of all the files that are subject to removal. This will not cleanup any logs or perform any action against the logs.
If the –
DeleteLogs
parameter used with the –SimulateDeleteLog
, the –DeleteLogs
is ignored.
.\Clean-ExchangeLogFiles.ps1 -SimulateDeleteLogs
Using LogsOlderXDays Parameter
The LogsOlderXDays
Parameter removes logs older than X number of days. For example, if logs older than 10 days should be removed, then use this parameter with an argument of 10, no need to add the minus sign.
The default value is 1 and can be set to a higher value
.\Clean-ExchangeLogFiles.ps1 -LogsOlderXDays 10
Using the ExtraFolderToAdd Parameter
Use the ExtraFolderToAdd
parameter to include other folders to be cleaned, for example, the Windows Temp folder.
Keep in mind that
ExtraFolderToAdd
parameter is using the same filter, so it’s only for .LOG and .ETL files
The type of the ExtraFolderToAdd
parameter is an array so the format of the argument is @(‘path1′,’path2’). Multiple paths can be added to the array using the comma as a separator. UNC path or Environment paths such as %TEMP% are not supported, the path should be the local path.
.\Clean-ExchangeLogFiles.ps1 -ExtraFolderToAdd @("C:\Windows\Temp","C:\root")
Using DeleteLogs Parameter
The DeleteLogs
parameter triggers the Remove-Item
operation and the script start removing logs and ETL files based on the folder provided.
Once the DeleteLogs
start, NO user input confirmation is required. Instead, there is a Ten seconds countdown before the operation start. This makes it easier for using it in ScheduleTask so the script won’t require any user input
.\Clean-ExchangeLogFiles.ps1 -DeleteLogs
Its expected that the script may skip or fail in removing some files as they are in use.
Parameters Conjunction
The following parameter can be used together as they are in the same ParameterSet
- DeleteLogs
- SimulateDeleteLogs
- LogsOlderXDays
- ExtraFolderToAdd
And the following parameter can be used together
- JustCalculate
- LogsOlderXDays
- ExtraFolderToAdd
Conculsion
I made this script to make the log removal very simple and won’t require changing any hard-coded value. Still, this is a script, and I might make some mistakes, use it at your own risk, and if you find any issue or bug, feel free and send a pull request or message me to fix it.
What about Performance Statistics in \Logging\Diagnostics\DailyPerformanceLogs?
In my environment it consume about 6GB (30% of Logging directory)
Hi Thanks for your comment.
I updated the script to include the BLG file (DailyPerformanceLog)
feel free to use the script again as it will remove these logs too.
download the lastest version from the same repo
Hello. Thank you for this very good powershell.
May be am I wrong but it seems there is not a full recursive process on
C:\Program Files\Microsoft\Exchange Server\V15\logging
The script return a size of 450Mb and with command dir *.log /s I have a size of 7Gb !
Any idea ?
Yes, and this is because the script search only for some extension, such as .Log, blg and etl, these extension are safe to delete
there will be other extension such as .bak which might consume space too
Please run the following line to see the total space consumed by other extension
$FolderList1='C:\Program Files\Microsoft\Exchange Server\V15\logging'
$AllItemsSize11= (@(Get-ChildItem $FolderList -Recurse | Where-Object {((get-date).AddDays(-$Olderthan)) -and ($_.PSIsContainer -like $false) -and (($_.Extension -notlike "*.log") -and ($_.Extension -notlike "*.blg") -and ($_.Extension -notlike "*.etl"))}).foreach({$_.length }))
($AllItemsSize11 | Measure-Object -Sum).Sum
also you run run the following line to see what are these files, Feel free to share with me the extension list to see the possibilty of including it in a next release.
Get-ChildItem $FolderList -Recurse | Where-Object {((get-date).AddDays(-$Olderthan)) -and ($_.PSIsContainer -like $false) -and (($_.Extension -notlike "*.log") -and ($_.Extension -notlike "*.blg") -and ($_.Extension -notlike "*.etl"))}
I hope that help. Let me know if you have any questions.
Thank you for your answer. The problem was elsewhere. I modified as described bellow to get the result I need. There was one day missing explaining the difference between the script and the dir *.log /s command.
Thank you again.
[ValidateScript({If ([int]$_ -gt 0) {
$True
} Else {
Throw “Number Of LogsOlderXDays Should Be 1 Or Higher.”
# }})]$LogsOlderXDays=1,
# BL 16/06/2022 : modified to 0 to get total content size
}})]$LogsOlderXDays=0,
Thanks for the comment and update,
First you forgot to mention that we have to run “Set-ExecutionPolicy Unrestricted” before running your script.
Secondly running your command “.\Clean-ExchangeLogFiles.ps1 -JustCalculate” it result for me a lot of reds lines
I would be very grateful if you guide me if there is something I dd wrong to can see it working.
Secondly: with my experience with Exchange the fyle types who can be safety deleted older than 2-3 days .blg / .csv / .log / .etl
int he following directory including sub-directorates
C:\Program Files\Microsoft\Exchange Server\V15\Logging\
C:\Program Files\Microsoft\Exchange Server\V15\Bin\Search\Ceres\Diagnostics\
C:\Program Files\Microsoft\Exchange Server\V15\TransportRoles\Logs\
Hi
would you please share the error you are getting? as a first thought, I think it’s normal as some files are in use or the script cannot access the directory
The script is removing the mentioned folder and some additional folders that contain the .blg, .log, .ETL file extension.
Also, you can specify additional folders to include in the cleanup process.