PSRotateLog.psm1
function Compress-IISLog { <# .SYNOPSIS Performs gzip compression of IIS logs .DESCRIPTION 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. .EXAMPLE Compress-IISLogs -SourceDirectory D:\Log -DestinationDirectory D:\Archive #> #region Params [CmdletBinding()] param( # Source directory to read files from [Parameter(Position = 0, Mandatory = $true)] [ValidateScript( {Test-Path -Path $_ -PathType 'container'})] [System.IO.DirectoryInfo] $Path, # Destination directory to write archives to [Parameter(Position = 1, Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] $Destination ) #endregion $SourceDirectory = $Path $DestinationDirectory = $Destination 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 if ($(Test-Path -Path "$containedDir") -eq $false) { New-Item -Path "$containedDir" -ItemType directory|Out-Null } try { Compress-File -InputFile $curFile -OutputFile "$containedDir\$($curFile.Name).gz" Remove-Item -Path $curFile } catch {throw $_} } } } } function Compress-File { #region Params param( [Parameter(Position = 0, Mandatory = $true)] [ValidateScript( {Test-Path -Path $_ -PathType 'leaf'})] [System.String] $InputFile, [Parameter(Position = 1, Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] $OutputFile ) #endregion 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 $_ } } function Get-FileList { [OutputType([System.IO.FileInfo])] #region Param param( [Parameter(Position = 0, Mandatory = $true)] [ValidateScript( {Test-Path -Path $_ -PathType 'Container'})] [System.IO.DirectoryInfo] $Path, [Parameter(Position = 1, Mandatory = $false)] [bool] $ListEmptyFolders = $false ) #endregion process { Get-ChildItem -Recurse -Force $Path|ForEach-Object { $fileCurrent = $_ $itemIsFolder = $fileCurrent.Attributes -band [System.IO.FileAttributes]::Directory $folderIsEmpty = $ListEmptyFolders -and (Get-ChildItem -Path $fileCurrent.FullName).Count -eq 0 $itemIsReparsePoint = $fileCurrent.Attributes -band [System.IO.FileAttributes]::ReparsePoint $itemToBeRemoved = (!$itemIsFolder -or ($itemIsFolder -and $folderIsEmpty)) -and !$itemIsReparsePoint if ($itemToBeRemoved) { Write-Output $fileCurrent } } } } function Remove-IISLogSize { [OutputType([System.IO.FileInfo])] #region Param Param( [Parameter(Mandatory = $true, ValueFromPipeline = $false, Position = 0)] [ValidateScript( {{Test-Path -Path $_ -PathType 'container'}})] [System.IO.DirectoryInfo] $Path, [Parameter(Mandatory = $true, ValueFromPipeline = $false, Position = 1)] [ValidateNotNullOrEmpty()] [System.Int64] $Size ) #endregion #Converting to List, otherwise array is fixed size $sortedList = [System.Collections.Generic.List`1[[System.Object, mscorlib, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089]]](Get-FileList -Path $Path|Sort-Object CreationTime) $folderSize = ($sortedList| Measure-Object -property length -sum).Sum try { while ($folderSize -gt $Size) { $item = $sortedList[0] Remove-Item -Path $item.FullName $sortedList.RemoveAt(0) $folderSize -= $item.Length Write-Output $item } } catch { throw $_ } } function Remove-IISLogCount { #region Param Param( [Parameter(Mandatory = $true, ValueFromPipeline = $false, Position = 0)] [ValidateScript( {{Test-Path -Path $_ -PathType 'container'}})] [System.IO.DirectoryInfo] $Path, [Parameter(Mandatory = $true, ValueFromPipeline = $false, Position = 1)] [ValidateNotNullOrEmpty()] [System.Int64] $KeepFiles ) #endregion $sortedList = Get-FileList -Path $Path|Sort-Object CreationTime #Number of files for removing $removeCount = $sortedList.Count - $KeepFiles try { if ($removeCount -gt 0) { $sortedList|Select-Object -First $removeCount|ForEach-Object { Remove-Item -Path $_.FullName Write-Output $_ } } } catch { throw $_ } } function Remove-IISLogOlder { #region Param Param( [Parameter(Mandatory = $true, ValueFromPipeline = $false, Position = 0)] [ValidateScript( {{Test-Path -Path $_ -PathType 'container'}})] [System.IO.DirectoryInfo] $Path, [Parameter(Mandatory = $true, ValueFromPipeline = $false, Position = 1)] [ValidateNotNullOrEmpty()] [System.DateTime] $Older, [Parameter(Position = 1, Mandatory = $false)] [bool] $RemoveEmptyFolders = $false ) #endregion try { Get-FileList -Path $Path -ListEmptyFolders $RemoveEmptyFolders|Where-Object {$_.LastWriteTime -lt $Older}|ForEach-Object { Remove-Item -Path $_.FullName Write-Output $_ } } catch { throw $_ } } function Remove-IISLog { <# .SYNOPSIS Removes logs .DESCRIPTION Log removing based on directory size, files count, files age .EXAMPLE C:\PS> Remove-IISLog -Path C:\Inetpub\Logs -FolderSize 100MB Removes old files and keeps only 100MB of the newest files .EXAMPLE C:\PS> Remove-IISLog -Path C:\Inetpub\Logs -KeepFiles 10 Keeps 10 newest files .EXAMPLE C:\PS> Remove-IISLog -Path D:\Logs2 -Older ([datetime]::now.AddDays(-10)) Removes files older 10 days #> [CmdletBinding(DefaultParameterSetName = 'FolderSize')] [OutputType([System.IO.FileInfo])] #region Param Param( # Path to log directory [Parameter(Mandatory = $true, ValueFromPipeline = $false, Position = 0)] [ValidateScript( {{Test-Path -Path $_ -PathType 'container'}})] [System.IO.DirectoryInfo] $Path, # Folder size to keep [Parameter(Mandatory = $true, ValueFromPipeline = $false, Position = 1, ParameterSetName = 'FolderSize')] [ValidateNotNullOrEmpty()] [System.Int64] $FolderSize, # Number of files to keep [Parameter(Mandatory = $true, ValueFromPipeline = $false, Position = 1, ParameterSetName = 'FilesNumber')] [ValidateNotNullOrEmpty()] [System.Int64] $KeepFiles, # Remove files older than specified [Parameter(Mandatory = $true, ValueFromPipeline = $false, Position = 1, ParameterSetName = 'FilesAge')] [ValidateNotNullOrEmpty()] [System.DateTime] $Older, [Parameter(Position = 1, Mandatory = $false)] [switch] $RemoveEmptyFolders ) switch ($PSCmdlet.ParameterSetName) { 'FolderSize' { Remove-IISLogSize -Path $Path -Size $FolderSize break } 'FilesNumber' { Remove-IISLogCount -Path $Path -KeepFiles $KeepFiles break } 'FilesAge' { Remove-IISLogOlder -Path $Path -Older $Older -RemoveEmptyFolders $RemoveEmptyFolders break } } #endregion } |