Do you know that feeling when you have delivered a good working script and a few weeks later someone comes up to you saying "It ain`t working". Or that time that someone else of your team changed some code over night and some parts  of your nice working tool ain't working anymore. For these reason I have developed 2 functions so you can compute file hashes and validate if your files have been changed. Other use cases for these functions are : 

With the first function you can create file hashes of a single file or a entire folder with subfolders. The hashes and the file path will be saved in a csv file so you can use them later to validate if something has been changed. The functions support the following hash algorithms: "SHA1","SHA256","SHA384","SHA512","MACTripleDES","MD5","RIPEMD160". Because you calculate a file hash you can even move the files from one computer to the next and still validate if the files are integer. Do note the files need to be on the same location or you have to replace the location in the csv integrity file.  

For a more detailed description of this function look at my site: http://www.tech-savvy.nl

-----------------------------------------------------------------------------------------------------------------------------------

Function name : Create-FileIntegrityHash
Authors        : Martijn (Scriptkiddie) van Geffen        
Version        : 1.0       
dependancies   : This function is dependant on the function "Validate-FileIntegrityHash"                       
    This function can be found on: Http://www.tech-savvy.nl
-----------------------------------------------------------------------------------------------------------------------------------       
-----------------------------------------------------------------------------------------------------------------------------------       
Version Changes:        Date: (dd-MM-YYYY)    Version:     Changed By:           Info:       
 05-01-2017            V0.1         Martijn van Geffen    Initial script       
 20-03-2017            V1.0         Martijn van Geffen    Released to TechNet       
-----------------------------------------------------------------------------------------------------------------------------------

 

-----------------------------------------------------------------------------------------------------------------------------------

Function name : Create-FileIntegrityHash
Authors       : Martijn (Scriptkiddie) van Geffen
Version       : 1.0
dependancies  : This function is dependant on the function "Create-FileIntegrityHash"
                        This function can be found on: Http://www.tech-savvy.nl
----------------------------------------------------------------------------------------------------------------------------------- 
-----------------------------------------------------------------------------------------------------------------------------------

Version Changes:        Date: (dd-MM-YYYY)    Version:     Changed By:           Info:  
       05-01-2017            V0.1         Martijn van Geffen    Initial script
       20-03-2017            V1.0         Martijn van Geffen    Released to TechNet
-----------------------------------------------------------------------------------------------------------------------------------

 

 

PowerShell
Edit|Remove
function Create-FileIntegrityHash 
{ 
    <# 
    .SYNOPSIS 
        Compute a file integrity hash for a file or folder with files. The output can be used to determine if a file is changed later on. 
    .DESCRIPTION 
        The only way to know if someone changed a file or anything in a folder with files is to calculate the hash of the files and compare 
        them with a hash computed at a earlier moment in time.  
 
        This function will compute a hash file for all the files in a folder. The output can be used later on with the function  
        "Validate-FileIntegrityHash" to validate if the files are still integer or if some has made changes. 
    .EXAMPLE 
        Create-FileIntegrityHash 
     
        Create a Filehash file for all files and files in the subfolder of the current folder. Use MD5 as the algorithm. 
    .EXAMPLE 
        Create-FileIntegrityHash -path d:\temp\test -algorithm "sha256" -exclude "*.ps1" 
     
        Create a Filehash file for all files and subfolders of the folder "d:\temp\test" Use "SHA256" as the algorithm and exclude "ps1"  
        files. 
    .INPUTS 
        Inputs to this cmdlet (if any) 
    .OUTPUTS 
        CSV file 
    .NOTES 
        ----------------------------------------------------------------------------------------------------------------------------------- 
        Function name : Create-FileIntegrityHash 
        Authors       : Martijn (Scriptkiddie) van Geffen  
        Version       : 1.0 
        dependancies  : This function is dependant on the function "Validate-FileIntegrityHash" 
                        This function can be found on: Http://www.tech-savvy.nl 
        ----------------------------------------------------------------------------------------------------------------------------------- 
        ----------------------------------------------------------------------------------------------------------------------------------- 
        Version Changes: 
        Date: (dd-MM-YYYY)    Version:     Changed By:           Info: 
        05-01-2017            V0.1         Martijn van Geffen    Initial script 
        20-03-2017            V1.0         Martijn van Geffen    Released to TechNet 
        ----------------------------------------------------------------------------------------------------------------------------------- 
 
    .COMPONENT 
        None 
    .ROLE 
        None 
    .FUNCTIONALITY 
        Compute file hash to be used later as comparison 
    #> 
[CmdletBinding(DefaultParameterSetName="Default",  
        HelpUri = 'https://gallery.technet.microsoft.com/Create-and-Validate-File-9077475e' 
    )] 
 
    param( 
        [Parameter(Mandatory=$false, 
            ParameterSetName="Default")] 
        [Parameter(ParameterSetName="filter")] 
        [Parameter(ParameterSetName="exclude")] 
        [ValidateNotNullOrEmpty()] 
        [string]$path = (get-item -path ".\").fullname, 
 
        [Parameter(Mandatory=$false, 
            ParameterSetName="exclude")] 
        [ValidateNotNullOrEmpty()] 
        [array]$exclude, 
 
        [Parameter(Mandatory=$false, 
            ParameterSetName="filter")] 
        [ValidateNotNullOrEmpty()] 
        [string]$filter, 
 
        [Parameter(Mandatory=$false, 
            ParameterSetName="Default")] 
        [Parameter(ParameterSetName="filter")] 
        [Parameter(ParameterSetName="exclude")] 
        [ValidateNotNullOrEmpty()] 
        [Validateset("SHA1","SHA256","SHA384","SHA512","MACTripleDES","MD5","RIPEMD160")] 
        [string]$Algorithm = "SHA512", 
 
        [Parameter(Mandatory=$false, 
            ParameterSetName="Default")] 
        [Parameter(ParameterSetName="filter")] 
        [Parameter(ParameterSetName="exclude")] 
        [ValidateNotNullOrEmpty()] 
        [ValidatePattern("[.][c][s][v]$")] 
        [string]$integrityfile = ((get-item -path ".\").fullname + "\FileIntegrityHash.csv") 
    ) 
 
    if (!([string]::IsNullOrEmpty($exclude))) 
    { 
        [array]$excluded +$integrityfile.split("\")[-1] 
        [array]$excluded +$exclude 
     
        $files = Get-ChildItem -Recurse -Path $path -File -Exclude $excluded 
 
    }elseif (!([string]::IsNullOrEmpty($filter))) 
    { 
        $files = Get-ChildItem -Recurse -Path $path -File -filter $filter 
 
    }else 
    { 
        $files = Get-ChildItem -Recurse -Path $path -File 
    } 
 
 
    $hashtable = @() 
    foreach ($file in $files ) 
    { 
 
      $hash = Get-FileHash -Path $file.fullname - 
} 
} 
 
####    END OF CODE SNIPPET USE DOWNLOAD TO GET FULL SCRIPT #### 
 
function Validate-FileIntegrityHash 
{ 
    <# 
    .SYNOPSIS 
        Validate a file integrity hash for a file or folder with files. The output can be used to determine if a file is changed/new or is 
        removed. 
    .DESCRIPTION 
        The only way to know if someone changed a file or anything in a folder with files is to calculate the hash of the files and compare 
        them with a hash computed at a earlier moment in time.  
 
        This function will validate the folder or file from a hash file created with the function "Create-FileIntegrityHash".  
    .EXAMPLE 
        Validate-FileIntegrityHash 
     
        validate a Filehash file for a set of folders or files previously created with create-fileintegrityhash. use the default location  
        ".\FileIntegrityHash.csv" as input csv and use the default "MD5" as hash algorithm. 
    .EXAMPLE 
        Validate-FileIntegrityHash -path d:\temp\test -algorithm "sha256" 
     
        validate a Filehash file for a set of folders or files previously created with create-fileintegrityhash. use the default location  
        ".\FileIntegrityHash.csv" as input csv and use "SHA256" as hash algorithm. 
    .EXAMPLE 
        Validate-FileIntegrityHash -integrityfile "c:\temp\FileIntegrityHash.csv" -filter "*.ps1" -outputfile d:\temp\output.txt 
     
        validate a Filehash file for the current folder use the file "c:\temp\FileIntegrityHash.csv"  previously created with  
        create-fileintegrityhash as input. Output the result to the file "d:\temp\output.txt". Use the default hash algorithm. 
    .INPUTS 
        Inputs to this cmdlet (if any) 
    .OUTPUTS 
        Output from this cmdlet (if any) 
    .NOTES 
        ----------------------------------------------------------------------------------------------------------------------------------- 
        Function name : Create-FileIntegrityHash 
        Authors       : Martijn (Scriptkiddie) van Geffen  
        Version       : 1.0 
        dependancies  : This function is dependant on the function "Create-FileIntegrityHash" 
                        This function can be found on: Http://www.tech-savvy.nl 
        ----------------------------------------------------------------------------------------------------------------------------------- 
        ----------------------------------------------------------------------------------------------------------------------------------- 
        Version Changes: 
        Date: (dd-MM-YYYY)    Version:     Changed By:           Info: 
        05-01-2017            V0.1         Martijn van Geffen    Initial script 
        20-03-2017            V1.0         Martijn van Geffen    Released to TechNet 
        ----------------------------------------------------------------------------------------------------------------------------------- 
 
    .COMPONENT 
        None 
    .ROLE 
        None 
    .FUNCTIONALITY 
        validate and report file hash 
    #> 
[CmdletBinding(DefaultParameterSetName="Default",  
        HelpUri = 'https://gallery.technet.microsoft.com/Create-and-Validate-File-9077475e' 
    )] 
 
    param( 
        [Parameter(Mandatory=$false, 
            ParameterSetName="Default")] 
        [Parameter(ParameterSetName="filter")] 
        [Parameter(ParameterSetName="exclude")] 
        [ValidateNotNullOrEmpty()] 
        [string]$Path = (get-item -path ".\").fullname, 
 
        [Parameter(Mandatory=$false,ParameterSetName="exclude")] 
        [ValidateNotNullOrEmpty()] 
        [array]$Exclude, 
 
        [Parameter(Mandatory=$false,ParameterSetName="filter")] 
        [ValidateNotNullOrEmpty()] 
        [string]$Filter, 
 
        [Parameter(Mandatory=$false, 
            ParameterSetName="Default")] 
        [Parameter(ParameterSetName="filter")] 
        [Parameter(ParameterSetName="exclude")] 
        [ValidateNotNullOrEmpty()] 
        [string]$Integrityfile = ((get-item -path ".\").fullname + "\FileIntegrityHash.csv"), 
             
        [Parameter(Mandatory=$false, 
            ParameterSetName="Default")] 
        [Parameter(ParameterSetName="filter")] 
        [Parameter(ParameterSetName="exclude")] 
        [ValidateNotNullOrEmpty()] 
        [Validateset("SHA1","SHA256","SHA384","SHA512","MACTripleDES","MD5","RIPEMD160")] 
        [string]$Algorithm = "SHA512", 
 
        [Parameter(Mandatory=$false, 
            ParameterSetName="Default")] 
        [Parameter(ParameterSetName="filter")] 
        [Parameter(ParameterSetName="exclude")] 
        [ValidateNotNullOrEmpty()] 
        [string]$Outputfile 
    ) 
 
    $hashtable = import-csv -Path $integrityfile 
     
    if (!([string]::IsNullOrEmpty($exclude))) 
    { 
        [array]$excluded +$integrityfile.split("\")[-1] 
        [array]$excluded +$exclude 
     
        $files = Get-ChildItem -Recurse -Path $path -File -Exclude $excluded 
 
    }elseif (!([string]::IsNullOrEmpty($filter))) 
    { 
        $files = Get-ChildItem -Recurse -Path $path -File -filter $filter 
 
    }else 
    { 
        $files = Get-ChildItem -Recurse -Path $path -File 
    } 
 
    $hashtablenow = @() 
    $Report = @() 
    foreach ($file in $files ) 
    { 
 
      $hash = Get-FileHash -Path $file.fullname -Algorithm $Algorithm 
      $hashtablenow +$hash 
   
    } 
 
    #calculate Integer and changed files 
    $result = Compare-Object -ReferenceObject $hashtable -DifferenceObject $hashtablenow -Property "Hash","path" -IncludeEqual 
    [array]$integerfiles = $result | Where-Object -FilterScript { $_.sideindicator -eq "==" } 
    [array]$changedfiles = $result | Where-Object -FilterScript { $_.sideindicator -eq "=>" } 
     
    #calculate removed files 
    $result2 = Compare-Object -ReferenceObject $hashtable -DifferenceObject $hashtablenow -Property "path" 
    [array]$removedfiles = $result2 | Where-Object -FilterScript { $_.sideindicator -eq "<=" } 
     
    if ($integerfiles.count -ge 1) 
    { 
        Write-output -InputObject "`nThe following files are Integer and have not been changed:`n" 
        $Report +"`nThe following files are Integer and have not been changed:`n" 
        foreach ( $item in $integerfiles ) 
        { 
           Write-output -InputObject "File: $($item.path)" 
           $Report +"File: $($item.path)" 
        } 
    } 
 
    Write-output -InputObject "`n" 
    $Report +=  "`n" 
    if ($changedfiles.count -ge 1) 
    { 
        Write-warning -message "`nThe following files are changed or New !!!!" 
        $Report +"`nThe following files are changed or New !!!!" 
        foreach ( $item in $changedfiles ) 
        {    
            if ( $item.SideIndicator -eq "=>") 
            { 
                Write-output -InputObject "Hash: $($item.hash) `t File: $($item.path) " 
                $Report +"Hash: $($item.hash) `t File: $($item.path) " 
            } 
        }     
    } 
 
    Write-output -InputObject "`n" 
    $Report +"`n" 
    if ($removedfiles.count -ge 1) 
    { 
        Write-warning -message "`nThe following file is  
 
####    END OF CODE SNIPPET USE DOWNLOAD TO  
GET FULL SCRIPT #### 
 
####    END OF CODE SNIPPET USE DOWNLOAD TO GET FULL SCRIPT #### 
 
####    END OF CODE SNIPPET USE DOWNLOAD TO GET FULL SCRIPT ####