Skip to main content

PowerShell script to compress IIS logs. Reads original logs from source directory and saves compressed logs to destination directory. The original files will be deleted after compression. The script won't rotate files which have been modified today.

<#PSScriptInfo
.VERSION 1.0
.GUID cd35b292-e0b9-4a6e-9cb5-94345e5a5108
.AUTHOR Vasily Larionov
.COMPANYNAME
.COPYRIGHT
.TAGS Compress,Log
.LICENSEURI
.PROJECTURI https://github.com/vlariono/posh-scripts
.ICONURI
.EXTERNALMODULEDEPENDENCIES
.REQUIREDSCRIPTS
.EXTERNALSCRIPTDEPENDENCIES
.RELEASENOTES
#>

<#
.SYNOPSIS
    Performs gzip compression of IIS logs

.DESCRIPTION
    Rotates IIS logs. Reads original logs from source directory and saves compressed
    logs to destination directory. The original files will be deleted after
    compression. The script won't rotate files which have been modified today.

.PARAMETER SourceDirectory
    Source directory to read files from

.PARAMETER DestinationDirectory
    Destination directory to write archives to

.EXAMPLE
    .\Compress-IISLogs.ps1 -SourceDirectory D:\Log -DestinationDirectory D:\Archive
#>

param
(
    [Parameter(Position=0, Mandatory=$true)]
    [ValidateScript({Test-Path -Path $_ -PathType 'container'})]
    [System.String] $SourceDirectory,

    [Parameter(Position=1, Mandatory=$true)]
    [ValidateNotNullOrEmpty()]
    [System.String]
    $DestinationDirectory
)

function Compress-File{
    param
    (
        [Parameter(Position=0, Mandatory=$true)]
        [ValidateScript({Test-Path -Path $_ -PathType 'leaf'})]
        [System.String]
        $InputFile,

        [Parameter(Position=1, Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [System.String]
        $OutputFile
    )

    try {
        #Creating buffer with size 8MB
        $bytesGZipFileBuffer = New-Object -TypeName byte[](8192)

        $streamGZipFileInput = New-Object -TypeName System.IO.FileStream($InputFile,[System.IO.FileMode]::Open,[System.IO.FileAccess]::Read)
        $streamGZipFileOutput = New-Object -TypeName System.IO.FileStream($OutputFile,[System.IO.FileMode]::Create,[System.IO.FileAccess]::Write)
        $streamGZipFileArchive = New-Object -TypeName System.IO.Compression.GZipStream($streamGZipFileOutput,[System.IO.Compression.CompressionMode]::Compress)

        for($iBytes = $streamGZipFileInput.Read($bytesGZipFileBuffer, 0,$bytesGZipFileBuffer.Count);
            $iBytes -gt 0;
            $iBytes = $streamGZipFileInput.Read($bytesGZipFileBuffer, 0,$bytesGZipFileBuffer.Count))
        {
            $streamGZipFileArchive.Write($bytesGZipFileBuffer,0,$iBytes)
        }

        $streamGZipFileArchive.Dispose()
        $streamGZipFileInput.Close()
        $streamGZipFileOutput.Close()

        Get-Item $OutputFile
    }
    catch { throw $_ }
}


Get-ChildItem -Path $SourceDirectory -Recurse -Exclude "*.gz"| ForEach-Object {
    if ($($_.Attributes -band [System.IO.FileAttributes]::Directory) -ne [System.IO.FileAttributes]::Directory) {
        # Current file
        $curFile = $_

        # Check the file wasn't modified today
        if ($curFile.LastWriteTime.Date -ne [System.DateTime]::Today) {
            $containedDir=$curFile.Directory.FullName.Replace($SourceDirectory,$DestinationDirectory)

            # if target directory doesn't exist - create it
            if ($(Test-Path -Path "$containedDir") -eq $false) {
                New-Item -Path "$containedDir" -ItemType directory
            }

            Write-Host $("Archiving " + $curFile.FullName)
            Compress-File -InputFile $curFile.FullName -OutputFile $("$containedDir\" + $curFile.Name + ".gz")
            Remove-Item -Path $curFile.FullName
        }
    }
}