Sunday, August 26, 2012

IIS Logs Cleanup in Powershell


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
#     http://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:\logs\weblogs\"
$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:\logs\weblogs\W3SVC782946685") 
$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:\logsfiles\W3SVC782946685") 
$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 = "$TempFolder\listfile.txt" 
 
# Temp file used to write the 7-Zip verify results to, then read into the email message body 
$ArchiveResults = "$TempFolder\archive-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 files\7-Zip\7z.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.

No comments:

Post a Comment