PS 2.0 – Remove and compress IIS logs automatically

I created a PS script for removing and compressing IIS log files.


  • Define variables: the log folder $LogFolder (basically it could be %SYSTEMROOT%\System32\LogFiles\W3SVC) and the retention periods ($DeletionRetention = -120, $CompressionRetention = -60).
  • Scripts handles only files with expired retention for attribute LastWriteTime  (e.g. -120 = older than 120 days).
  • It deletes all* files with expired retention ($DeletionRetention) from the log folder. (* Be careful, the folder doesn’t have to contain only logs.)
  • It compresses log files with expired retention ($CompressionRetention) into one zip based on month number from LastWriteTime ( Number 2502132135 is the time stamp.
  • The script can be simply scheduled via Windows Task Scheduler if needed (e.g. Trigger: Monthly – last day).HowToScheduleScript


I used in my script zip functions from David Aiken – Compress Files with Windows PowerShell then package a Windows Vista Sidebar Gadget


$LogPath = "D:\IISLogs"
$DeletionRetention = -120
$CompressionRetention = -60

function New-Zip
 set-content $zipfilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
 (dir $zipfilename).IsReadOnly = $false

function Add-Zip

 if(-not (test-path($zipfilename)))
 set-content $zipfilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
 (dir $zipfilename).IsReadOnly = $false 

 $shellApplication = new-object -com shell.application
 $zipPackage = $shellApplication.NameSpace($zipfilename)

 foreach($file in $input) 
 Start-sleep -milliseconds 500

function Get-Zip
 $shellApplication = new-object -com shell.application
 $zipPackage = $shellApplication.NameSpace($zipfilename)
 $zipPackage.Items() | Select Path

$Items = get-childitem $LogPath

$DeleteLogs = $Items | ? {$_.LastWriteTime -le (Get-Date).adddays($DeletionRetention)}
if($DeleteLogs -ne $null) { $DeleteLogs | %{Remove-Item $_.fullname}}

$Items = get-childitem $LogPath |? {($_.extension -like "*.log") -and ($_.LastWriteTime -le (Get-Date).adddays($CompressionRetention))}

$GroupedItems = $Items | sort LastWriteTime | select @{n='Month';e={$_.LastWriteTime.month}},fullname,length,name | group month

if($GroupedItems -ne $null){
 foreach ($GroupedItem in $GroupedItems){
 $MonthNumber = $GroupedItem.Name
 $Time = Get-Date -Format ddMMyyHHss
 $ZipPath = "$LogPath\IISLogs-Month$MonthNumber-$"
 New-Zip $ZipPath
 $ | select fullname,length | %{
 Get-Item $_.fullname | Add-Zip $ZipPath
 start-sleep -s ($_.Length/20000000)
 if((Get-Zip $ZipPath).length -eq $GroupedItem.Count){
 $ | %{Remove-Item $_.fullname}
 Write-Host "`nERROR - Files are not zipped correctly. Deletion process skipped."
 $ | %{$}




We can remove logs also by command Forfiles (thank you Lukas).



8 thoughts on “PS 2.0 – Remove and compress IIS logs automatically

  1. Hi cool script!

    But I have a little problem….
    My ISS Logs are stored in the following folders:

    I tried this: $LogPath = “C:\inetpub\logs\LogFiles\” but it didnt work.

    how can I indicate multiple folders in the variable LOG PATH?
    Hopefully you can help me 🙂

    • Hello,
      you should use for get-childitem command parameter -recurse (gets the items in the specified locations and in all child items of the locations.):

      $LogPath = “C:\inetpub\logs\LogFiles\”
      $Items = get-childitem $LogPath -recurse

      In this case is needed to change also the following:
      $Items = $Items |? {($_.extension -like “*.log”) -and ($_.LastWriteTime -le (Get-Date).adddays($CompressionRetention))}


      • hi Filip,

        thx for the fast response.
        I have my script updated with your code, but now I am getting this error:

        You cannot call a method on a null-valued expression.
        At D:\SharePoint\Script\IIS_Logs\IISLog-Removing-Compressing-v1.ps1:29 char:22
        + $zipPackage.CopyHere <<<< ($file.FullName)
        + CategoryInfo : InvalidOperation: (CopyHere:String) [], RuntimeException
        + FullyQualifiedErrorId : InvokeMethodOnNull

        The archive was created but it includes no files(logs).


      • Hi,
        if you run only these lines in PS runspace, shall variables $Items and $GroupedItems contain any data?
        $LogPath = “C:\inetpub\logs\LogFiles\”
        $Items = get-childitem $LogPath -recurse
        $Items = $Items |? {($_.extension -like “*.log”) -and ($_.LastWriteTime -le (Get-Date).adddays($CompressionRetention))}
        $GroupedItems = $Items | sort LastWriteTime | select @{n=’Month’;e={$_.LastWriteTime.month}},fullname,length,name | group month

        Variables can be shown by using:


  2. hi,
    somehow i cannot press reply on your last post……..

    I run these lines in as a new script. Then i let me show the variables $Items and $GroupedItems.
    I got a list of all the logfiles($Items).
    And the variable $GroupedItems contains this:
    Count Name Group
    —– —- —–
    5 4 {@{Month=4; FullName=C:\TEMP\IIS_LOG_BAK2\LogFiles\W3SVC1297401274\u_ex1…
    138 5 {@{Month=5; FullName=C:\TEMP\IIS_LOG_BAK2\LogFiles\W3SVC1235617185\u_ex1…
    23 6 {@{Month=6; FullName=C:\TEMP\IIS_LOG_BAK2\LogFiles\W3SVC1263836887\u_ex1…

    Is that correct? I think it is.


  3. I am using the CopyHere() Method to extract a file from the Archive. The script runs great using PowerShell directly and runs from the scheduled task. When running from scheduled task, the CopyHere() Method never extracts any files.

    Any thoughts?


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s