IIS Log File Maintenance

Tagged: 

This topic contains 15 replies, has 6 voices, and was last updated by Profile photo of Bob McCoy Bob McCoy 1 year, 2 months ago.

  • Author
    Posts
  • #13560
    Profile photo of Nathan Hartley
    Nathan Hartley
    Participant

    I am in the process of changing my server build-out scripts to DSC and am being forced to deal with an IIS Log File Maintenance routine, I cobbled together years back.

    Right now, it is a separate script (one for 2003, one for 2008, there was some incompatibility with 2012 I haven't dealt with) that I run on all servers with IIS. The script finds the log drive, creates a new Log folder, creates an Archive and a Bin folder within that, puts an archiving/purging script and the Info-Zip executable in the bin folder, then creates a scheduled task to run the script every night. I'd like to also add changing all IIS log paths to this location to the script.

    Before I go any further (custom DSC Resource?) I wanted to ask the community, how are you handling IIS's lack of a built-in log maintenance solution?

    This seems like a basic feature that IIS should have by now. Maybe I'm missing something.

    Thanks,
    Nathan

  • #13561
    Profile photo of Don Jones
    Don Jones
    Keymaster

    Good God, I was literally typing a note to Steve Murawski about this. It says:

    I'm running into a thing where people read “configuration” and think “provisioning.” So they think, “well, DSC is only useful when I set up a server or need to change its role, but I still need PowerShell scripts for maintenance.” Which isn't true.

    I'd like a simple resource that deals with file archiving and rotation.

    E.g., specify a source path, an optional archive path, a max file age, and an optional max archive file age. Also specify an archive action, “Archive” or “Delete.” There'd be no “ensure.”

    If you specify Delete, then any files in the source path older than MaxFileAge get deleted.

    if you specify Archive, then any files in the source path older than MaxFileAge get moved to the archive path; any files in the archive path older than MaxArchiveFileAge get deleted.

    Simple (hopefully), but demonstrates that ongoing maintenance is also a form of “configuration.”

    Which is basically what you're asking for. So there's nothing built in, but a custom DSC resource would indeed do it, and would be a great way to go.

  • #13568
    Profile photo of Tore Groneng
    Tore Groneng
    Participant

    hi,

    Maybe I am missing your point, however are you talking about how you should configure logfile rollover/retention so that it does not fill up your disk or are you talking about what IIS logs into the logfile?

  • #13571
    Profile photo of Don Jones
    Don Jones
    Keymaster

    Log file management – e.g., rollover and archival. The end point was, no, IIS doesn't do it natively, and yes, a custom DSC resource would deb a good way to go about it, if your servers have PowerShell v4 installed.

  • #13572
    Profile photo of Nathan Hartley
    Nathan Hartley
    Participant

    Sorry, yes, roll-over and retention is indeed what I am after.

  • #13579
    Profile photo of Tore Groneng
    Tore Groneng
    Participant

    hi again,

    Don is almost correct 🙂 We have rollover natively in IIS, however no achiving of items of an certain age. So custom DSC it is then or you could use a DSC script Resource while you develop you custom DSC resource.

    To get you started (below code will give you the current logfile settings):


    Import-Module WebAdministration
    $site = get-item IIS:\Sites\MyNewSite
    $site.logfile

    I snipped the above code from this link:

    http://stackoverflow.com/questions/4626791/powershell-command-to-set-iis-logging-settings

  • #13612
    Profile photo of Nathan Hartley
    Nathan Hartley
    Participant

    Yes, IIS does have some facility for doing file roll-overs, but my old script actually Zipped the files daily and stored them in an archive folder for X days before deleting them.

    I think the quick and dirty solution will be to:

    • Create the new Log Folder, outside of the System Drive, with the File Resource.
    • Set the IIS hourly roll-over and change the logging path to the new location (thanks for the code), looks like this needs to be a Script Resource for now.
    • Then create a scheduled task with a Script Resource to simply purge the log folder. Probably with my old standby below...
    
    powershell.exe -command "&{Get-ChildItem e:\logs\* -Include ex*.log -Recurse  | Where-Object {$_.LastWriteTime -lt (Get-Date).AddDays(-7)} | Remove-Item }"
    
  • #13623
    Profile photo of Tore Groneng
    Tore Groneng
    Participant

    hi,

    Looks like a good plan. Best of luck 🙂

    Cheers

  • #13646
    Profile photo of Nathan Hartley
    Nathan Hartley
    Participant

    I'm close... The LCM doesn't seem to have permission to create the Scheduled Job. The following code returns, "This event indicates that a non-terminating error was thrown when DSCEngine was executing Set-TargetResource on MSFT_ScriptResource provider. FullyQualifiedErrorId is UnauthorizedAccessToRegisterScheduledJobDefinition,Microsoft.PowerShell.ScheduledJob.RegisterScheduledJobCommand. ErrorMessage is An access denied error occurred when registering scheduled job definition PurgeLogFolder. Try running Windows PowerShell with elevated user rights; that is, Run As Administrator.."


    configuration LogDirectory
    {
    param ([string[]]$Node)
    node $Node
    {
    Script LogDirectoryScript
    {
    GetScript = {
    $job = Get-ScheduledJob PurgeLogFOlder
    [ordered]@{
    FolderPresent= (Test-Path C:\log)
    JobId = $job.Id
    JobName = $job.Name
    JobEnabled = $job.Enabled
    JobCommand = $job.Command
    }
    }

    SetScript = {
    # Create directory
    if ( -not (Test-Path C:\log)) {
    New-Item -ItemType Directory -Path C:\log
    }

    # Change permissions such that any user can write.
    $acl = (Get-Item C:\log).GetAccessControl('Access')
    $acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule("Users","Write", "Allow")))
    Set-Acl -Path C:\log -AclObject $acl | Out-Host

    # Schedule purge task
    if ([bool](Get-ScheduledJob PurgeLogFOlder -ErrorAction SilentlyContinue)) {
    Unregister-ScheduledJob -Name PurgeLogFolder
    }
    $script = {Get-ChildItem C:\log\* -Include ex*.log -Recurse | Where-Object {$_.LastWriteTime -lt (Get-Date).AddDays(-7)} | Remove-Item}
    $trigger = New-JobTrigger -Daily -At 23:59:59
    Register-ScheduledJob -Name PurgeLogFolder -ScriptBlock $script -Trigger $trigger
    }

    TestScript = {
    (Test-Path C:\log) -and [bool](Get-ScheduledJob PurgeLogFOlder -ErrorAction SilentlyContinue)
    }
    }
    }
    }

  • #13647
    Profile photo of Don Jones
    Don Jones
    Keymaster

    Lcm runs as system, so it might well not. You might need to provide a credential.

  • #13648
    Profile photo of Nathan Hartley
    Nathan Hartley
    Participant

    I knew LCM ran as System. It seemed like LCM should have been able to create a Scheduled Job, as System, to run as System, and I'd be all set.

    As you can tell, I was trying to skate around the whole "having to create an account just to purge files" thing.... (Why isn't this built into IIS???)

  • #13678
    Profile photo of Nathan Hartley
    Nathan Hartley
    Participant

    In the end... I cheated. I just do not have time, at the moment, to take this any further.

    Thank you for your help!

    Ironically, I can only use this on our Server 2008 R2 servers. Our current version of ESX does not support 2012 R2. So the 2012 servers that I hoped to configure with DSC, will have to wait. (Don, your rant the other night came to mind when I discovered this situation.)


    configuration LogDirectory
    {
    param (
    [Parameter(Mandatory)]
    [ValidateNotNullOrEmpty()]
    [string[]]$Node
    )
    node $Node
    {
    Script LogDirectoryScript
    {
    GetScript = {
    $result = (Test-Path 'E:\log') -and (schtasks.exe /query /TN Purge_Log_Folder | Select-String Purge_Log_Folder -Quiet)
    return @{
    GetScript = $GetScript
    SetScript = $SetScript
    TestScript = $TestScript
    Result = $result
    }
    }
    SetScript = {
    Write-Verbose 'Creating log directory.'
    if ( -not (Test-Path 'E:\log')) {
    New-Item -ItemType Directory -Path 'E:\log'
    }
    Write-Verbose 'Changing permissions to log directory such that any user can write, but only an administrator can read or modify.'
    $acl = (Get-Item 'E:\log').GetAccessControl('Access')
    $acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule('Users','Write', 'Allow')))
    Set-Acl -Path 'E:\log' -AclObject $acl | Out-Host
    Write-Verbose 'Scheduling purge task.'
    $script = 'Get-ChildItem E:\log\* -Include ex*.log -Recurse | Where-Object {$_.LastWriteTime -lt (Get-Date).AddDays(-7)} | Remove-Item'
    Set-Content -Path C:\Windows\Purge_Log_Folder.ps1 -Value $script
    $task = 'Powershell.exe -NoProfile -ExecutionPolicy RemoteSigned -File C:\Windows\Purge_Log_Folder.ps1'
    SCHTASKS /CREATE /TN Purge_Log_Folder /TR $task /SC DAILY /ST 23:59 /RU SYSTEM /F | Out-Host
    Write-Verbose 'Configuring IIS'
    # Default Log File Settings for Web Sites
    # http://www.iis.net/configreference/system.applicationhost/sites/sitedefaults/logfile
    Import-Module WebAdministration
    Set-WebConfigurationProperty '/system.applicationHost/sites/siteDefaults' -name logFile -value @{
    directory = 'E:\log'
    localTimeRollover ='true'
    period = 'Hourly'
    }
    }
    TestScript = {
    (Test-Path 'E:\log') -and (schtasks.exe /query /TN Purge_Log_Folder | Select-String Purge_Log_Folder -Quiet)
    }
    }
    }
    }

  • #13751
    Profile photo of Vern Anderson
    Vern Anderson
    Participant

    I know this is not PowerShell but I have been using this service for years and years...

    It's a third party utility that runs as a service and manages archiving your IIS Logs for you. It is actually on my RADAR to get around to making a PowerShell equivelent which I am working on but I wanted to use built in Windows ZIP and not 7zip or some 3rd party command line ZIP tool. I have the COM Object for ZIPPING but just haven't had time to finish the script. Probably because this 3rd party tool works really well and has served my company for many years.

    -VERN

  • #35363
    Profile photo of Joakim Svendsen
    Joakim Svendsen
    Participant

    Here's my take on this, which also includes some sanity checking on the log file names (optional). Guess that has been covered, though, didn't realize when writing the article.

    Automatically delete old IIS logs with PowerShell

  • #35427
    Profile photo of Vern Anderson
    Vern Anderson
    Participant
  • #35433
    Profile photo of Bob McCoy
    Bob McCoy
    Participant

    I run this script weekly on an IIS server via the task scheduler.

    # Script to be run weekly by task scheduler to cleanup IIS files
    # greater than 30 days old.
    #
    # Bob McCoy 3/27/14
    
    $start = (get-date).AddDays(-30)
    
    # Clean up old log files
    Get-ChildItem C:\inetpub\logs\LogFiles -File -Recurse | where LastWriteTime -lt $start | Remove-Item
    
    # Get rid of bounced mail files
    Get-ChildItem C:\inetpub\mailroot\Badmail -File -Recurse | where LastWriteTime -lt $start | Remove-Item
    

You must be logged in to reply to this topic.