Public/Get-OriAzBopFolderHash.ps1

<#
.SYNOPSIS
    Compute Hash of the folder
 
.DESCRIPTION
    Compute Hash of the folder
 
.PARAMETER Path
    The Path to folder to compute the Hash
 
.PARAMETER ExcludePath
    Exclude Path is path to the Manifest file (.PSD1 suffix)
 
 
.EXAMPLE
Get-OriAzBopFolderHash `
-Path c:\temp\
# Should return something like this:
# 5cfdcbf97b7a004f387c69d6b1dab25b
 
#>


function Get-OriAzBopFolderHash {
    [CmdLetBinding()]
    param (
        [Parameter(Mandatory = $True, HelpMessage = "The Path to folder to compute the Hash")]
        [ValidateScript( { Test-Path $_ })]
        [String] $Path,

        [Parameter(Mandatory = $False, HelpMessage = "Exclude Path is path to the Manifest file (.PSD1 suffix)")]
        [String[]] $ExcludePath
    )
    $ErrorActionPreference = 'Stop'
    Write-Verbose -Message ("[ START: {0}:{1} (v.{2}) ]" -f $Local:MyInvocation.MyCommand.Source, $Local:MyInvocation.MyCommand.Name, $Local:MyInvocation.MyCommand.Version)
    foreach ($arg in $PSBoundParameters.GetEnumerator()) {
        if ([string]::IsNullOrEmpty($arg.Value)) {
            Write-Debug -Message ("[null] {0}: {1}" -f $arg.Key, $arg.Value) -ErrorAction SilentlyContinue 
        }
        else {
            Write-Debug -Message ("[{2}] {0}: {1}" -f $arg.Key, $arg.Value, $arg.Value.GetType().Name) -ErrorAction SilentlyContinue 
        }
    }
    $ExcludePath += "*.tests.ps1"
    $ExcludePath += ".*" # There can be e.g. files like .gitignore
    $ExcludePath += "PSGetModuleInfo.xml"

    

    $ToReturn = Invoke-OriAzExrExceptionRetry `
        -ListedExceptions @('Access to the path*is denied.', 'Administrator rights are required to install or update.', 'The process cannot access the file') `
        -ScriptBlockToRun `
    {
        [CmdletBinding()]
        param
        (   
            [Parameter(Mandatory = $true, HelpMessage = "Path to the module")]
            [string] $Path,
                
            [Parameter(Mandatory = $true, HelpMessage = "Exclude path")]
            [string] $ExcludePath
        )
        $md5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
        [string] $ToReturn = [System.BitConverter]::ToString($md5.ComputeHash([System.Text.Encoding]::UTF8.GetBytes((
                        Get-ChildItem -Path $Path -Recurse -Exclude $ExcludePath -File `
                        | Where-Object { (Split-Path $_.Directory -leaf) -ne 'Obsolete' } `
                        | Where-Object { (Split-Path $_.Directory -leaf) -ne 'Tests' } `
                        | Get-Content  -Raw ))))
        return $ToReturn
    } `
        -MaxRetry 30 `
        -SleepTimeInSec 10


    # CleanUp of separator and make it all upper cases
    $ToReturn = $ToReturn.ToUpper().Replace('-', '')

    <#
    $HashCollector = Get-ChildItem -Path $Path -Recurse -Exclude $ExcludePath -File `
    | Where-Object { (Split-Path $_.Directory -leaf) -ne 'Obsolete' } `
    | Where-Object { (Split-Path $_.Directory -leaf) -ne 'Tests' } `
    | Get-FileHash -Algorithm MD5
 
    $allBytes = new-object System.Collections.Generic.List[byte]
    foreach ($OneHashCollector in $HashCollector) {
        $allBytes.AddRange([System.Text.Encoding]::UTF8.GetBytes($OneHashCollector.Hash))
        $allBytes.AddRange([System.IO.File]::ReadAllBytes($file.FullName))
        $allBytes.AddRange([System.Text.Encoding]::UTF8.GetBytes($file.Name))
    }
    $hasher = [System.Security.Cryptography.MD5]::Create()
    $ToReturn = [string]::Join("", $($hasher.ComputeHash($allBytes.ToArray()) | ForEach-Object { "{0:x2}" -f $_ }))
 
     
    $ToReturn = $HashCollector.Hash
    #>

    Write-Debug "hash of $Path is [$ToReturn]."
    Write-Verbose -Message ("[ END: {0} ]" -f $Local:MyInvocation.MyCommand.Name)
    return $ToReturn

}