Sunday, December 18, 2011

Archive IIS Log Files

The following script is using 7Zip to compress IIS Log files.  It identifies IIS Log folder and parses through the contents to find the log files older than $days.  It zips them up, and delete the original log files. The resulting compressed archive will be about 4.5% of the size of the original log files.

# Windows PowerShell Script ###############################################

# NAME:  Archive_IIS_Log_Files.ps1

# COMMENT:  The script parse through the IIS logs directory contents to find the log files
#   older than $days. Zip them up, and delete the original 
#           log files. The resulting compressed archive will be about 
#           4.5% of the size of the original log files.

# REQUIRED: 7-Zip is required for this to work. By default this script 
#           looks for the 7-Zip executable, 7za.exe, in C:\Program Files\7-Zip\
#
# Running Scripts Without Starting Windows PowerShell
#   powershell.exe -noexit c:\MyScripts\Archive_IIS_Log_Files.ps1
#
# Scheduling Action: powershell.exe c:\MyScripts\Archive_IIS_Log_Files.ps1
########################################################################### 
Function Archive_IIS_Log_Files{
 $strComputer = "."
 $days = "7"
 $exe = 'C:\Program Files\7-Zip\7z.exe'
 $emailFrom = "noreply@server.com"
 $emailTo = "admin@server.com"
 $subject = "Scheduled job 'Archive IIS Log Files' failed"
 $body = "Error in : "
 $smtpServer = "smtp.mail.com"
 Write-host "`r` "
 Write-host "`r` "
 Write-host "`t` `t` Start process `t` `t` "  -foregroundcolor Black -backgroundcolor White
 Write-host "`r` "
 Write-host "`t` `t` Inluding .Net Web.Administration"  -foregroundcolor "Green"
 [System.Reflection.Assembly]::LoadFile( "C:\windows\system32\inetsrv\Microsoft.Web.Administration.dll")
 $iis = new-object Microsoft.Web.Administration.ServerManager
 Write-host "`r` "
 Write-host "`t` `t` Achive logs for the following websites: `t` `t` "  -foregroundcolor DarkCyan
 $iis.sites | select-object Id, Name
 $TopFolder = $IIS.SiteDefaults.LogFile.Directory
 $TopFolder = $TopFolder -replace "%SystemDrive%", "C:"
 Write-host "`t` `t` Folders to process:" -foregroundcolor DarkCyan
 Get-ChildItem -path $TopFolder | select pspath
 Write-Host "To cancel the process, Press ‘Ctrl + C’" -foregroundcolor Yellow
 Start-sleep -s 5
 foreach ($site in $iis.sites){
  $TargetFolder = "$TopFolder\W3SVC"
  $TargetFolder = $TargetFolder += $site.Id
  $zipName = Get-Date -format 'yyyy_MM_dd_HH_mm_ss'
  $zipName = "$TargetFolder\$zipName.logs.zip"
  Write-host "`r` "
  Write-Host "Zip file: " $zipName -foregroundcolor DarkCyan
  $SiteName = GetSiteNameForByLogFolder $TopFolder  $TargetFolder
  Write-host "Processing logs for: $SiteName" -foregroundcolor "Yellow"
  if (Test-Path $TargetFolder){
   #Warn you the targeted folder, so you can double check
   Write-host "`r` "
   Write-host "The Targeted Folder is:" $TargetFolder -foregroundcolor DarkCyan
   $Now = Get-Date
   # Notice the minus sign before $days
   $LastWrite = $Now.AddDays(-$days)
   $Files = get-childitem $TargetFolder -include *.log -recurse |Where {$_.LastWriteTime -le "$LastWrite"}
   If ($Files -eq $NULL){
    write-host "No files for processing." -foregroundcolor Green
    return
   }
   try{
    foreach ($File in $Files){
     Write-host "`r` "
     Write-host "Running: " $exe a $zipName $File -foregroundcolor Yellow
     & $exe a $zipName $File
     Write-host "`r` "
     write-host "Deleting File $File" -foregroundcolor "Red"
     #You can add -whatif to see the consequence – Remove-item $File -Whatif
     $File.Delete()
    }
    #throw $_.exception
   }
   catch{
    #Send error message
    $body = "$body$File"
    $smtp = new-object Net.Mail.SmtpClient($smtpServer)
    $smtp.Send($emailFrom, $emailTo, $subject, $body)
    Write-Error  $body
   }
  } Else {
   Write-host "`r` "
   Write-Host "The Folder $TargetFolder Does Not Exist!"
  }
 }
 Write-host "`r` "
 Write-host "`t` `t` End process `t` `t` "  -foregroundcolor Black -backgroundcolor White
}
Function GetSiteNameForByLogFolder($TopFolder , $TargetFolder){
 $TargetFolderLength = $TargetFolder.Length
 $TopFolderLength = "$TopFolder\W3SVC".Length
 $SiteID = $TargetFolder.substring($TopFolderLength,$TargetFolderLength - $TopFolderLength)
 Write-host "`r` "
 [System.Reflection.Assembly]::LoadFile( "C:\windows\system32\inetsrv\Microsoft.Web.Administration.dll")
 $iis = new-object Microsoft.Web.Administration.ServerManager
 foreach ($site in $iis.sites){
  if  ($site.id -eq $SiteID){
   $SiteName = $Site.Name
   break
  }
 }
 return $SiteName
}
Archive_IIS_Log_Files

If you find this script useful please donate generously.