File Change Tripwire

A simple PowerShell script to monitor selected folders/filetypes for changes, then e-mail results.



  1. Ian
    This PowerShell script will monitor your selected folders for any created, modified, renamed or deleted files. You'll then be e-mailed a list of all the changes at a set interval, along with a time and details of each filename. This script could be set to run in the background to monitor important folder for security intrusions - for example, on a Windows based webserver.

    All of the variables you need to configure are listed in the first two blocks of code. You'll need an SMTP server to take advantage of the e-mail capability, but this can easily be edited out if desired.

    You'll need to create a "/Logs" sub-directory in the location of the PS file, this is used as a local log folder.

    To Do List:
    • Excluded File Filters
    • Multiple Folder Monitoring
    • Automatic Log folder Creation
    • Optional E-Mail and Logging Settings

    Code (PowerShell):
    #   __          ___           _                  __  ___  ______                                              
    #   \ \        / (_)         | |                /_ |/ _ \|  ____|                                              
    #    \ \  /\  / / _ _ __   __| | _____      _____| | | | | |__ ___  _ __ _   _ _ __ ___  ___   ___ ___  _ __ ___
    #     \ \/  \/ / | | '_ \ / _` |/ _ \ \ /\ / / __| | | | |  __/ _ \| '__| | | | '_ ` _ \/ __| / __/ _ \| '_ ` _ \
    #      \  /\  /  | | | | | (_| | (_) \ V  V /\__ \ | |_| | | | (_) | |  | |_| | | | | | \__ \| (_| (_) | | | | | |
    #       \/  \/   |_|_| |_|\__,_|\___/ \_/\_/ |___/_|\___/|_|  \___/|_|   \__,_|_| |_| |_|___(_)___\___/|_| |_| |_|
    #
    #
    # PowerShell Script Repository: https://www.windows10forums.com/articles/categories/powershell-scripts.8/
    # Author: Ian Cunningham

    ### MONITORING SETTINGS

        $serverName = "Host1"   #server name
        $emailFreq = "5"   #number of minutes between e-mail notification batches
        $monitorFolder = "C:\inetpub\vhosts"   #folder to monitor
        $fileFilter = @(".txt",".doc",".xls",".zip")   #array of extensions to monitor

    ### EMAIL SETTINGS

        $From = "test@test.com"
        $To = "test@test.com"
        $SMTPServer = "smtp.test.com"
        $SMTPPort = "587"
        $Username = "test@test.com"
        $Password = "password"


    ### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
        $filewatcher = New-Object System.IO.FileSystemWatcher
        $filewatcher.Path = $monitorFolder
        $filewatcher.Filter = "*.*"
        $filewatcher.IncludeSubdirectories = $true
        $filewatcher.EnableRaisingEvents = $true

    ### STARTUP VARS

        $global:body = @()
        $global:changes = $false
        $global:firsttimestamp = $(Get-Date)


    ### DEFINE ACTIONS AFTER A EVENT IS DETECTED
     
        $fileaction = {
     
                    $path = $Event.SourceEventArgs.FullPath
                    $extension = [io.path]::GetExtension($path)

                    if ($fileFilter -contains $extension) {

                            $changeType = $Event.SourceEventArgs.ChangeType
                            $logline = "$(Get-Date), ${changeType}: $path"
                            Add-content "$PSScriptRoot\Logs\$(get-date -f yyyy-MM-dd).txt" -value $logline
                     
                            $global:body += $logline
                            $global:body += "`r`n"

                            if ($global:changes -eq $false) {

                                $global:changes = $true
                                $global:firsttimestamp = $(Get-Date)

                            }
                    }

                  }


    ### DECIDE WHICH EVENTS SHOULD BE WATCHED + SET CHECK FREQUENCY
        $filecreated = Register-ObjectEvent $filewatcher "Created" -Action $fileaction
        $filechanged = Register-ObjectEvent $filewatcher "Changed" -Action $fileaction
        $filedeleted = Register-ObjectEvent $filewatcher "Deleted" -Action $fileaction
        $filerenamed = Register-ObjectEvent $filewatcher "Renamed" -Action $fileaction

    while ($true) {
        sleep 1

        if ((($(Get-Date) - ($global:firsttimestamp)).TotalMinutes -ge $emailFreq) -AND ($global:changes -eq $true)) {

        $smtp = New-Object System.Net.Mail.SmtpClient($SMTPServer, $SMTPPort);
        $smtp.EnableSSL = $true
        $smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password);
        $smtp.Send($From, $To, "File Change Log - $serverName", $global:body);

        Write-Host "E-Mail Sent"
        Write-Host $global:body

        $global:changes = $false
        $global:body = @()

        }

    }
    Regedit32 likes this.