Automatically delete old IIS logs with PowerShell

From Svendsen Tech PowerShell Wiki
Jump to: navigation, search

Here are a few short, simple PowerShell code examples on how to delete old IIS logs (Internet Information Services logs), that are well-suited for being run as a scheduled task on a server. Here is an article that talks more about managing IIS logs, and it has a VBScript example for deleting from all the log folders. I will discuss a few options related to that.

After I identify the active IIS log directory that's filling up the precious space on the C: drive (or another drive), something like the code below is what I end up using most of the time. See the article on managing IIS that there's a link to above for how to identify the folder; basically it's under "Logging" in the IIS console, under the relevant site's information. Or you can usually just browse the usual X:\inetpub folder structure in File Explorer.

I added "#requires -version 2", which should make it abort if run on a system with PowerShell 1.x. This code will only work with PowerShell version 2 and up (default in Server 2008 R2 / Windows 7 - and available for Server 2003 R2 and XP).

The code examples below should be stored in files named "Remove-OldIISLogs.ps1", or whatever you want to name them, but make sure they have the .ps1 extension.




Target specific directory only

Automatically-delete-old-logs.png

As text for pasting, etc.

#requires -version 2
$IISLogDir = 'C:\inetpub\logs\LogFiles\W3SVC4'
[int] $DaysOfHistoryToKeep = 30
$PastDate = (Get-Date).AddDays((-1 * $DaysOfHistoryToKeep)) # 30 days ago, cached
Get-ChildItem -LiteralPath $IISLogDir -Include *.log | # or try -Path "$IISLogDir\*.log"
    # Where-Object { $_.Name -match '^u_ex\d+\.log$' } |
    Where-Object { -not $_.PSIsContainer } | # target only files in a PSv2-compatible way
    Sort-Object -Property LastWriteTime |
    #Select-Object -Skip 5 | # "Comment in" to keep the five oldest logs...
    Where-Object { $_.LastWriteTime -lt $PastDate } |
    Remove-Item #-WhatIf

See this article, or try searching the web, for how to set it up as a scheduled task. I recommend running it as the local "NT AUTHORITY\SYSTEM" user, whether the user is logged on or not, and with highest privileges. This user has access to the server's local disks by default, and you won't need to enter credentials (those might expire/change).

Best practices for easier tracking (anything else?) would be an AD service account. If the logs are on a network share, use an AD service account (that you or someone else create), or you could still use the SYSTEM account and grant the AD computer object account ("DOMAIN\servername$") permissions to modify/delete from the share. That's moving into more hairy setups, though.

Notice how I have the parameter "-WhatIf" commented out for "Remove-Item" on the last line. If you remove the comment symbol "#", it will print out all the files it would delete without actually deleting them. Good during testing. Or simply remove or comment out the "Remove-Item" command (and pipe at the end of the line above) to be safer still.

Also notice this part:

# | Where-Object { $_.Name -match '^u_ex\d+\.log$' } |

If you remove the comment symbol "#" from that, it will only delete files that match the pattern "starts with u_ex, followed by digits, ends with .log". This is if you want to make sure you only target the IIS default log file names on at least Server 2008 R2 with IIS6 and IIS7. This might need tweaking.

Also notice how I use "-Include *.log" for Get-ChildItem, so it targets only files with the extension ".log".

Recursively delete from all log folders

This is a slightly modified version of the same code as above, but now one level higher up in the directory structure, and with the "-Recurse" parameter for Get-ChildItem, to target all the W3SVCxx folders. Still filtering only on files with the "log" extension.

Otherwise, the same comments as for the code above apply. You may want to not comment out the -WhatIf parameter for Remove-Item on the last line during testing, or remove it entirely.

#requires -version 2
$IISLogDir = 'C:\inetpub\logs\LogFiles'  ## one level higher up here!
[int] $DaysOfHistoryToKeep = 30
Get-ChildItem -LiteralPath $IISLogDir -Include *.log -Recurse | # with -Recurse
    # Where-Object { $_.Name -match '^u_ex\d+\.log$' } |
    Where-Object { -not $_.PSIsContainer } | # target only files in a PSv2-compatible way
    Sort-Object -Property LastWriteTime |
    #Select-Object -Skip 5 | # "Comment in" to keep the five oldest logs...
    Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays((-1 * $DaysOfHistoryToKeep)) } |
    Remove-Item #-WhatIf

That's just about all there is to deleting old IIS logs from a PowerShell script in the cases I have come across so far.