Wednesday, July 9, 2014

Compress and Delete old IIS Logs

We have a single server that hosts OWA and ActiveSync services for the entire organization. This server generates IIS log files on a daily basis averaging around 1.5GB in size. After a month of web traffic, these log files quickly fill up the drive space and bring it to it's knees.

The purpose of this script is to clean-up the log files folder and keep it at a manageable size.

  1. Log files older than 7 days will be compressed into ZIP format. 
  2. ZIP files older than 30 days will be deleted.
If ran locally, the script can use the native windows compression tools, but I wanted it to run as a scheduled task. Without using 7-Zip, the script would create the ZIP file, but would never copy the file into the ZIP. 7-Zip is able to accomplish this for me. If it's installed, the script will favor 7-Zip over native tools (update path if you didn't use 32-bit version). I believe this is due to the fact that the copy method in the native compression is ran as a separate task. As a scheduled task, it is never spawned. This leaves a 1kb ZIP file in place. 

After running script the first time, you should find in your "C:\inetpub\logs\LogFiles\W3SVC1\" folder, the following items. 
  • ZIPs containing logs over 7 days old. 
  • The original log files that are in those ZIPs. 
Second run:
  • ZIPs over 30 days deleted.
  • Logs over 7 days with existing ZIP over 1kb deleted.


If I take out the support for native compression, I can safely have the script delete the old log files after compression. Until then, the script will always leave the old log files until a later run. To accommodate this, I've scheduled the script to run both Sunday and Monday. 



<#
.SYNOPSIS
   Compress then purge old IIS logs
.DESCRIPTION
   Looks for Log files over a certain date. 
     - Compress files that are over a certain date to ZIP format. 
  - Delete ZIP files that exceed longer date. 
   Uses 7ZIP if installed - needs it if running as a scheduled task.
       Download: http://7-zip.org/
   
#>

#variables for folder management

#Folder path to where the IIS logs reside.
$FolderPath = "C:\inetpub\logs\LogFiles\W3SVC1\"

#LOGS older than this date (-7 days ago) will be compressed.
$CompressLogsDate = (Get-Date).AddDays(-7)

#ZIPs older than this date (-30 days ago) will be deleted.
$OldestZIPDate = (Get-Date).AddDays(-30)


#Create ZIP scripts
function New-Zip {
 param([string]$zipfilename)
 set-content $zipfilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
 (  dir $zipfilename).IsReadOnly = $false
}

function Add-Zip {
 param([string]$zipfilename)

 if(-not (test-path($zipfilename))) {
  set-content $zipfilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
  (   dir $zipfilename).IsReadOnly = $false 
 }

 $shellApplication = new-object -com shell.application
 $zipPackage = $shellApplication.NameSpace($zipfilename)

 foreach($file in $Input) {
  $zipPackage.CopyHere($file.FullName)
  Start-sleep -milliseconds 500
 }
}

if (!(Test-Path $FolderPath)) {
 write-host "no log folder found at $folderpath"
 break
}

#Check to see if 7Zip installed.
$7ZipPath = "${Env:ProgramFiles(x86)}"+"\7-Zip\7z.exe" #32-bit path
#$7ZipPath = "$Env:ProgramFiles\7-Zip\7z.exe"   #64-bit path
$Use7Zip = (test-path $7ZipPath)

#Delete ZIPs over a specific date
$ZipPath = $FolderPath +"*.zip"
$RemoveZips = Get-ChildItem $ZipPath |?{$_.lastwritetime -lt $OldestZIPDate}
if ($RemoveZips) { #Delete ZIP files older than $OldestZIPDate.
 ForEach ($zip in $RemoveZips) {
  Remove-Item $zip.VersionInfo.FileName.tostring()
 }
}  

#Find Logs that are older than specific date.
$LogPath = $FolderPath +"*.log"
$Oldlogs = Get-ChildItem $LogPath |?{$_.lastwritetime -lt $CompressLogsDate}

if ($Oldlogs) { #Process old log files.
 ForEach ($Log in $Oldlogs) {
  $LogFileStr = $Log.VersionInfo.FileName.tostring()  
  $TempZipName = $LogFileStr.replace(".log",".zip")
  if (!(Test-Path $tempZipName)) { #Create a new ZIP if one doesn't exist
   if ($Use7Zip ) {
    #Use 7Zip if using a scheduled task. 
    set-alias sz $7ZipPath
    sz a -tzip $TempZipName $LogFileStr  
   } else {
    #Found this method doesn't work as a scheduled task. This only works if ran interactively.
    New-zip $tempZipName
    Get-Item $LogFileStr | add-zip $tempZipName
   }
  } else {
   $newZipFile = Get-Item $TempZipName 
   $CreatedTodayBool = $newZipFile.creationtime -gt (get-date).addhours(-1)
   if ($newZipFile.length -gt 1kb) { 
    #Delete original LOG file it ZIP is larger than creation size. 
    if (Test-Path $log) {Remove-Item $Log}
   } else {
    #Make sure not deleting zips created in last hour. Might still be compressing files. 
    if (!$CreatedTodayBool) {
     #Delete ZIP files that are only 1KB in size. 
     Remove-Item $tempZipName 
    }
   }
  } 
 }
}

No comments:

Post a Comment