IIS Logs Cleanup in Powershell

MrMobileWill iis, Other Projects, windows, work 0 Comments

Back in June I was working on cleaning up the IIS log files at work but I wanted to archive them instead of deleting them, just in case. I came across this script in Powershell.

http://gallery.technet.microsoft.com/scriptcenter/31db73b4-746c-4d33-a0aa-7a79006317e6

It works well but it needed the ability to archive a folder of folders instead of having to list each folder and the ability to backup previous months. So I updated it and I decided I would post it here in case it can help someone else.


#Windows PowerShell Code###################################################
#
# NAME: compress-remove-logs.ps1
# VERSION: 1.4.2
# DATE: 20120309
#
# AUTHOR: Bernie Salvaggio
# EMAIL: BernieSalvaggio(at)gmail(dot)com
# TWITTER: @BernieSalvaggio
# WEBSITE: http://www.BernieSalvaggio.com/
#
# COMMENT: Given one or more website directories, parse through the
# directory contents to find the previous month's IIS log
# files. Zip them up, verify the .zip, and delete the original
# log files. The resulting compressed archive will be about
# 4.5% of the size of the original log files.
#
# This script is best utilized by setting a scheduled task
# to run it during off-peak times because the compression
# process will max out all available cores unless you tell
# 7-Zip not to do so (in its own settings, not from this script)
#
# REQUIRED: 7-Zip is required for this to work. By default this script
# looks for the 7-Zip executable, 7za.exe, in C:7-Zip
#
# You have a royalty-free right to use, modify, reproduce, and
# distribute this script file in any way you find useful, provided that
# you agree that the creator, owner above has no warranty, obligations,
# or liability for such use.
#
# UPDATED: William Garrido 06/26/2012 - Added archive of previous months and backup all subfolders
# https://www.mobilewill.us
###########################################################################

#History settings
$months = -1
$startMonth = -1

# Build all the pieces for emailing results
$ServerName = gc env:computername
$SmtpClient = new-object system.net.mail.smtpClient
$MailMessage = New-Object system.net.mail.mailmessage
# Mail server settings for you to change according to your environment
$SmtpClient.Host = "localhost"
$MailMessage.from = ($ServerName + "@" + $ServerName)
$MailMessage.To.add("user@domain.com")
$MailMessage.Subject = $ServerName + " IIS Log File Archive Results"

#Use Subfolders
Set-Location "d:logsweblogs"
$dirs = Get-ChildItem $directory | Select-Object FullName | Where-Object {!($_.psiscontainer)} | foreach {$_.FullName}

# The folder(s) you want to back up
# IMPORTANT: For each target path you specify here, there MUST be a matching BackupsPath and TargetPathName defined as well.
#$TargetPaths = @("d:logsweblogsW3SVC782946685")
$TargetPaths = $dirs

# Where you want the backups saved
# There's a 1 to 1 relationship between the $BackupsPath and $TargetPaths
# For each $TargetPaths you add, you need another $BackupsPath to go along with it
#$BackupsPath = @("U:logsfilesW3SVC782946685")
$BackupsPath = $dirs

# Short name to append to the filename of the .zip backup file (in case the backup path is the same for multiple target paths)
# Each entry here should match the corresponding one in the $TargetPaths array
$TargetPathName = @("iis-logs")

# Temp file that stores the list of files for 7-Zip to archive
$TempFolder = "C:temp"
if (!(Test-Path $TempFolder)) { New-Item $TempFolder -type directory }
$ArchiveList = "$TempFolderlistfile.txt"

# Temp file used to write the 7-Zip verify results to, then read into the email message body
$ArchiveResults = "$TempFolderarchive-results.txt"
$ArchiveExtension = ".zip"

for ($x=$startMonth; $x -ge $months; $x--)
{

# Just some things to get started...
$TargetPathNameCounter = 0
$BackupPathCounter = 0
$CurrentDate = Get-Date
$ArchiveDate = $CurrentDate.AddMonths($x).ToString("MMMyyyy")
$FilesFound = $false

# Path to the 7-Zip executable
$7z = "C:program files7-Zip7z.exe"
if (!(Test-Path $7z)) {
$MailMessage.Body = "Error: 7-Zip not found at $7z"
$SmtpClient.Send($MailMessage)
Exit
}



write-host $x -nonewline
Write-Host $ArchiveDate -foregroundcolor red

foreach ($TargetPath in $TargetPaths) {
$FilesFound = $false

# Directory list, minus the folders, where the last write time = the archive date, group the files by month/year
dir $TargetPath | where {!$_.PSIsContainer} | where {$_.extension -eq ".log"} | where {"{0:MMM}{0:yyyy}" -f $_.LastWriteTime -eq $ArchiveDate} | group {"{0:MMM}{0:yyyy}" -f $_.LastWriteTime} | foreach {

# Used for tracking in case no files meeting the backup criteria are found
$FilesFound = $true

# Generate list of files to compress. For list files, 7-Zip uses UTF-8 encoding by default
$_.group | foreach {$_.fullname} | out-file $ArchiveList -encoding utf8

# Declare/Clear the email message body
$MailMessage.Body = ""

# Create the full name of the zip file we'll create
$ZipFileName = $BackupsPath[$BackupPathCounter]+$TargetPathName[$TargetPathNameCounter]+$_.name+$ArchiveExtension

# Archive the list of files
$null = & $7z a -tzip -mx8 -y $ZipFileName `@$ArchiveList

# Check if the operation succeeded
if($LASTEXITCODE -eq 0){
# If it succeeded, double check with 7-Zip's Test feature
$null = & $7z t $ZipFileName | out-file $ArchiveResults
if($LASTEXITCODE -eq 0){
# Verify success, write out the contents of the verify command to the email message body
foreach ($txtLine in Get-Content $ArchiveResults) {$MailMessage.Body += $txtLine + "`n"}
# Delete the original files
$_.group | Remove-Item
} else {
$MailMessage.Body = "There was an error verifying the 7-Zip archive $ZipFileName"
}
} else {
$MailMessage.Body = "There was an error creating the 7-Zip archive $ZipFileName"
}
$SmtpClient.Send($MailMessage)
}

if (!$FilesFound) {
# No files found to parse
$MailMessage.Body = "Error: No files found to archive in $TargetPath"
$SmtpClient.Send($MailMessage)
}

# Test to make sure the files exist before removing. If there aren't any files to archive, these two files won't exist.
if (Test-Path $ArchiveList) { Remove-Item $ArchiveList }
if (Test-Path $ArchiveResults) { Remove-Item $ArchiveResults }

$BackupPathCounter++
$TargetPathNameCounter++
}

}

Comment below if you found this useful.

Update: Looks like he made similar changes a few days ago.

Leave a Reply