For those of us who have been administering Windows web based servers know that one feature that IIS is known for is not rolling over its logs. Many admins have left logging off when not needing to debug or troubleshoot to work around this. In many enterprise environments, it’s import to maintain these logs to review for security issues.

So I initially created this script to trim the IIS logs on exchange servers. it will search for the exchange servers on your environment and remotely query IIS to locate the log directories. After which it will delete any logs older than the configured amount of days.

When Exchange 2013 came out, I updated the script to also truncate the Exchange logs, since Exchange 2013 was created with a large amount of logging, that again doesn’t truncate. The script will also locate the Exchange log files and truncate those logs as well.

Finally at the end, the script will send an email report of all files deleted from each server for record keeping. Follow the link below to download.


Used to trim IIS logs on Exchange 2013 servers
Because of the increased level of logging in Exchange 2013 I developed this script
to locate and truncate log files over a certain day length.
This script will find log files in the Default IIS logging location
and in the Exchange installation location
File Name : Clean-Logs.ps1
Author : Joshua Wortz (v1.0)
Prerequisite : PowerShell V2 over Vista and upper.
Versoion History : v1.0 23rd May 2015 : First Edition


$From = ""
$To = ""
$SMTPServer = "SMTPServer"

$days=30 #You can change the number of days here
#$IISLogPath ="C:\inetpub\logs"

Write-Host "Removing IIS and Exchange logs; keeping last" $days "days"

function Out-FileForce {
if(Test-Path $path)
Out-File -inputObject $_ -append -filepath $path
new-item -force -path $path -value $_ -type file

#Locating and Removing old Logs
Function CleanLogfiles($TargetFolder, $Server)
$targetfolder = $targetfolder -replace "%SystemDrive%", "c:"
$TargetServerFolder = "\\$($Server)\" + $TargetFolder.split(':')[0] + "$" + $TargetFolder.split(':')[1]
Write-Host $TargetServerFolder
if (Test-Path $TargetServerFolder) {
$Now = Get-Date
$LastWrite = $Now.AddDays(-$days)
$Files = Get-ChildItem $TargetServerFolder -Include *.log,*.blg -Recurse | Where {$_.LastWriteTime -le "$LastWrite"}

$files | Remove-Item -ErrorAction SilentlyContinue | out-null

$colItems = $files | Measure-Object -property length -sum

[string]$sum = "{0:N2}" -f ($colItems.sum / 1MB) + " MB"


Else {
Write-Host "The folder $TargetServerFolder doesn't exist! Check the folder path!" -ForegroundColor "red"

#gets the name of the Ex2015 servers
Function Get-ExchangeServerInDomain {

$search = new-object DirectoryServices.DirectorySearcher([ADSI]"LDAP://$configNC")
$objectClass = "objectClass=msExchExchangeServer"
$serialNumber = "serialNumber=Version 15.*"
$name = "name=DC*"#modify if naming schema is different
$search.Filter = "(&($objectClass)($serialNumber)($name))"
[void] $search.PropertiesToLoad.Add("name")
[void] $search.PropertiesToLoad.Add("serialNumber")
$search.FindAll() | %{$[0]}

[string]$Body = $null

#Gets list of Servers
[array]$Servers = Get-ExchangeServerInDomain

foreach ($Server In $Servers) {
[array]$logs = $null

#Queries IIS for log paths for Each IIS Site on Server
$IISLogPaths = Invoke-Command -ComputerName ($Server) -ScriptBlock {get-website | %{$_.logfile.Directory}}
$Body += "<H1>$Server</H1>"
#Delete log files from each IIS path
foreach ($Path in $IISLogPaths)

$logs += $path | select @{N="Path";e={$_}}, @{N="Size Deleted";e={$( CleanLogfiles -TargetFolder $Path -server $Server)}}


if($Exchange -eq $true)
#Get Path of Exchange Installation on remote server
$objReg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $Server)
$objRegKey= $objReg.OpenSubKey("SOFTWARE\\Microsoft\\ExchangeServer\\v15\\Setup\\")
[array]$ExchangeLoggingPath = $objRegkey.GetValue("MSiInstallPath") + "Logging\"
$exchangeloggingpath += "D:\Exchange\Logs"

$logs += $exchangeloggingpath | select @{N="Path";e={$_}}, @{N="Size Deleted";e={$(CleanLogfiles -TargetFolder $_ -server $Server)}}

$body += $logs | convertto-html -fragment


$head = @'
body { background-color:#dddddd;
font-size:12pt; }
td, th { border:1px solid black;
border-collapse:collapse; }
th { color:white;
background-color:black; }
table, tr, td, th { padding: 2px; margin: 0px }
table { margin-left:50px; }

[string]$html = convertto-html -Head $head -Body $body #| Out-File $reportFile -Force

Send-MailMessage -SmtpServer $SMTPServer -To $to -From $From -Body $html -Subject "IIS Logs Deleted" -BodyAsHtml

HTTP Redirection for Exchange


If you’ve ever installed Exchange 2010 or 2013, you can probably recall that first time you tried visiting OWA, and there it is the 403.4 error. Of course that small moment of panic sets in because you’re certain there were no errors with the install. Then after a few minutes of scouring the internet, you finally realize that you’re not crazy because this is by designed!


While I understand that the last thing we want is to expose our user’s login information over an HTTP connection, from a usability perspective it’s frustrating for users to have to remember to type https:// when trying to get to OWA. We can resolve this by going to the default site and disabling the require SSL and setting up a redirection. However,thanks to inheritance, you’ve just unknowingly disabled the requirement for SSL across the entire default site. Now we need to go to each of the various folders and enable the SSL requirement, but make sure that the PowerShell folder isn’t enabled or you’ll break the Exchange management shell.

After all of that, we still need to setup the redirect so that when people navigate to they get redirected to

So 30 minuets later I’ve fixed one of my Exchange servers, awesome! I got tired of going through this routine, so I cooked up a PowerShell script that will do the work for you. Hopefully you’ll find it useful as well!