Skip to content

Instantly share code, notes, and snippets.

@potatoqualitee
Last active February 28, 2022 12:33
Show Gist options
  • Save potatoqualitee/7b0e8b30c950a82fa218cebcabaa905e to your computer and use it in GitHub Desktop.
Save potatoqualitee/7b0e8b30c950a82fa218cebcabaa905e to your computer and use it in GitHub Desktop.

Revisions

  1. potatoqualitee revised this gist Feb 22, 2022. 1 changed file with 3 additions and 2 deletions.
    5 changes: 3 additions & 2 deletions Test-FileHash.ps1
    Original file line number Diff line number Diff line change
    @@ -64,11 +64,12 @@ function Test-FileHash {
    foreach ($file in $FilePath) {
    if ($file.FullName) {
    $filename = $file.FullName
    $current = Get-FileHash -Path $filename -Algorithm MD5 -ErrorAction SilentlyContinue
    } else {
    $filename = $file
    $current = Get-FileHash -Path $file -Algorithm MD5 -ErrorAction SilentlyContinue
    }

    $current = Get-FileHash -Path $filename -Algorithm MD5 -ErrorAction SilentlyContinue

    if (-not $baseline -and $current) {
    $original = $compare[$filename]
    if ($original -ne $current.Hash) {
  2. potatoqualitee created this gist Feb 22, 2022.
    108 changes: 108 additions & 0 deletions Test-FileHash.ps1
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,108 @@
    function Test-FileHash {
    <#
    .Synopsis
    This is a simple file hash comparison tool that writes to Windows Events when changes are detected
    .Description
    This is a simple file hash comparison tool that writes to Windows Events when changes are detected
    .PARAMETER FilePath
    The path to the file to hash and compare
    .PARAMETER DictionaryFile
    The path to the directionary file with previously calculated hashes
    Defaults to the current directory + compare.xml
    This file is created if it does not exist
    .NOTES
    Copyright: (c) 2022 by Chrissy LeMaire, licensed under MIT
    License: MIT https://opensource.org/licenses/MIT
    .Example
    PS> Test-FileHash -FilePath C:\indexes\index.json -DictionaryFile D:\audit\allhashes.xml
    Tests to see if the filehash of the file at C:\indexes\index.json has changed since the last time it was hashed.
    .Example
    PS> Get-ChildItem -Recurse -Path "C:\Program Files\Microsoft SQL Server" | Test-FileHash -DictionaryFile D:\audit\allhashes.xml
    Tests to see if the filehash of the file at C:\indexes\index.json has changed since the last time it was hashed.
    #>
    [CmdletBinding()]
    param (
    [parameter(ValueFromPipeline, Mandatory)]
    [Alias("FileName", "FullName")]
    [psobject[]]$FilePath, # this allows directories, gci and strings to be passed in
    [System.IO.FileInfo]$DictionaryFile = ".\compare.xml"
    )
    begin {
    # Test for admin -- it's needed to create the event log source
    $user = [Security.Principal.WindowsIdentity]::GetCurrent()
    $isadmin = (New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)

    if (-not $isadmin) {
    throw "You must run this script as administrator"
    }

    if ((Test-Path -Path $DictionaryFile)) {
    $compare = Import-CliXml -Path $DictionaryFile
    } else {
    $compare = $null
    $baseline = $true
    }

    if (-not ([System.Diagnostics.EventLog]::SourceExists("FileHash Checker"))) {
    $null = New-EventLog -LogName Application -Source "FileHash Checker"
    }

    $message = New-Object System.Collections.ArrayList
    $output = New-Object System.Collections.Hashtable
    }
    process {
    foreach ($file in $FilePath) {
    if ($file.FullName) {
    $filename = $file.FullName
    $current = Get-FileHash -Path $filename -Algorithm MD5 -ErrorAction SilentlyContinue
    } else {
    $filename = $file
    $current = Get-FileHash -Path $file -Algorithm MD5 -ErrorAction SilentlyContinue
    }
    if (-not $baseline -and $current) {
    $original = $compare[$filename]
    if ($original -ne $current.Hash) {
    $currenthash = $current.Hash
    $oldhash = $original
    if (-not $original) {
    $currentmessage = "$filename is a new file with a hash of $currenthash"
    } else {
    $currentmessage = "$filename had a previous hash of $oldhash but now has a hash of $currenthash"
    }
    $null = $message.Add($currentmessage)
    Write-Warning -Message $currentmessage
    }
    }
    if ($current) {
    $null = $output.Add($filename, $current.Hash)
    $current
    }
    }
    }
    end {
    if ($message) {
    # Just make one entry with all of the filehash failures
    $params = @{
    LogName = "Application"
    Source = "FileHash Checker"
    EntryType = "Warning"
    Category = 0
    EventId = 1000
    Message = ($message -join [Environment]::NewLine)
    }

    Write-EventLog @params
    }
    $null = $output | Export-CliXml -Path $DictionaryFile
    }
    }