PowerShell: Log Manager

In my environment, I need to keep an archive of some log files for a period of time, whereas other logs are not so critical, and some applications generate logs which are already compressed into ZIP files daily. So I have all these different requirements for logs. I don’t want them filling up my server hard drives and I don’t want to disable logging, so I wrote this script that could cater to these requirements.

This script is also available to download from the Microsoft TechNet Script Center.


Depending on your needs you can configure this script to do the following:

  • Delete files and folder trees older than X days.
  • Move files and folder trees to another location.
  • Archive files and folder trees as a ZIP file.

Compatibility and Requirements

The script has been tested on Windows 10, Windows Server 2016, Windows Server 2012 R2, and Windows Server 2008 R2. It has been used to manage Microsoft Deployment Toolkit logs, IIS log files, firewall logs, Minecraft Server logs, IRC client logs and the logs generated by my own scripts posted about here.

The PowerShell -file Parameter

When running the script via Schedule Tasks or the command prompt be sure to use the -file parameter before specifying the script, so you can use “double quotes” for the options that need them, if you do not use -file, then you should use ‘single quotes’.

Command Line Options

Here are the command line options available to you, with some examples of how to use them.

Command Line Switch Mandatory Description Example
-path Yes The location of the log files you wish to manage. C:\inetpub\logs\LogFiles\W3SVC*\*



-days Yes Entering 30 will mean that files older than 30 days will be managed. Any number greater than 0


-backup No* The location to copy the files to. *This switch is not mandatory, but must be used if a zip file is to be created. F:\Log-Archive



-workdir No Specify the location for the ZIP file to be created. Ideally it should be local to the server for best performance. E:\scripts
-l No Location to store the optional log file. The name of the log file is automatically generated. E:\scripts\log
-sendto No The email address to send the log to. me@contoso.com
-from No* The email address that the log should be sent from.

*This switch isn’t mandatory but is required if you wish to email the log file.

-smtp No* SMTP server address to use for the email functionality.

*This switch isn’t mandatory but is required if you wish to email the log file.






-user No* The username of the account to use for SMTP authentication.

*This switch isn’t mandatory but may be required depending on the configuration of the SMTP server.

-pwd No* The password of the account to use for SMTP authentication.

*This switch isn’t mandatory but may be required depending on your SMTP server.

-usessl No* Add this option if you wish to use SSL with the configured SMTP server.

Tip: If you wish to send email to outlook.com or office365.com you will need this.

*This switch isn’t mandatory but may be required depending on the configuration of the SMTP server.


Self aware note: I’m totally aware that my script is designed to manage logs and yet it will also generate a log, if required. I really like to get a notification when a server runs a script, so that’s why all of my scripts have this option. Some of my recent scripts generate a log file that gets overwritten each time they run, so they shouldn’t build up over time, but for everything else this script should help.

The Complete Script

# -------------------------------------------
# Script: Log-Manager_v1-4.ps1
# Version: 1.4
# Author: Mike Galvin twitter.com/digressive
# Date: 22/07/2017
# -------------------------------------------

## Set up command line switches and what variables they map to

## Count the number of files that are old enough to work on in the configured directory
$fileno = Get-ChildItem $worklogs –Recurse | Where-Object CreationTime –lt (Get-Date).AddDays(-$time) | Measure-Object

## If the number of the files to work on is zero, do nothing
If ($fileno.count -ne 0) {

    ## If logging is configured, set up variables and start logging
    If ($logpath) {
        $logfile = "cleanup-logs.log"
        $log = "$logpath\$logfile"
        Start-Transcript $log

    ## If the zip option was configured, copy the working files to a temp dir and create a zip file, then remove the temp dir and move the zip file
    If ($zip) {
        Add-Type -AssemblyName "system.io.compression.filesystem"
        New-Item -Path $zip\temp -ItemType Directory
        Get-ChildItem $worklogs | Where-Object CreationTime –lt (Get-Date).AddDays(-$time) | Copy-Item -Destination $zip\temp -Recurse -Force -Verbose
        [io.compression.zipfile]::CreateFromDirectory("$zip\temp", "$zip\Logs-{0:yyyy-MM-dd-HH-mm}.zip" -f (Get-Date))
        Remove-Item $zip\temp -Recurse -Verbose
        Move-Item $zip\Logs-*.zip $dest -Verbose
        Get-ChildItem $worklogs –Recurse | Where-Object CreationTime –lt (Get-Date).AddDays(-$time) | Remove-Item -Recurse -Verbose

    ## If the backup directory was configured, copy the files to the backup dir
    If ($dest) {
        Get-ChildItem $worklogs | Where-Object CreationTime –lt (Get-Date).AddDays(-$time) | Copy-Item -Destination $dest -Recurse -Force -Verbose

    ## If no backup options were configured, or after doing the previous operations, remove the old files
    Get-ChildItem $worklogs –Recurse | Where-Object CreationTime –lt (Get-Date).AddDays(-$time) | Remove-Item -Recurse -Verbose

    ## If log was configured stop the log
    If ($logpath) {

        ## If email was configured, set the variables for the email subject and body
        If ($smtpserver) {
            $mailsubject = "Log Manager Log"
            $mailbody = Get-Content -Path $log | Out-String

            ## If an email password was configured, create a variable with the username and password
            If ($smtppwd) {
                $smtpcreds = New-Object System.Management.Automation.PSCredential -ArgumentList $smtpuser, $($smtppwd | ConvertTo-SecureString -AsPlainText -Force)

                ## If ssl was configured, send the email with ssl
                If ($usessl) {
                    Send-MailMessage -To $mailto -From $mailfrom -Subject $mailsubject -Body $mailbody -SmtpServer $smtpserver -UseSsl -Credential $smtpcreds

                ## If ssl wasn't configured, send the email without ssl
                Else {
                    Send-MailMessage -To $mailto -From $mailfrom -Subject $mailsubject -Body $mailbody -SmtpServer $smtpserver -Credential $smtpcreds

            ## If an email username and password were not configured, send the email without authentication
            Else {
                Send-MailMessage -To $mailto -From $mailfrom -Subject $mailsubject -Body $mailbody -SmtpServer $smtpserver


Change Log

21/06/2017 1.4

  • Improved commenting on the code for documentation purposes.
  • Added authentication and SSL options for e-mail notification.

13/06/2017 1.3

  • First public release.

I hope this saves you future disk space headaches. If you’d like to get in touch with me please leave a comment or tweet me.


Follow Mike on Twitter: @Digressive

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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 )

Google+ photo

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

Connecting to %s