Skip to content

Powershell - Compare file hash with existing hash file (checksum, SHA1) to validate binary file integrity

A quick win you should add to your power shell scripts whenever you execute a binary file by doing an integrity check based on checksums.

$pathToBinaryFile = "/your/file.path"
$pathToSha1File = $($pathToBinaryFile + ".sha1")

If (test-path $pathToBinaryFile) {
    $calculatedFileHash = Get-FileHash -LiteralPath $pathToBinaryFile -Algorithm SHA1
    $sha1FileContent = Get-Content $pathToSha1File 

    Write-Host ":: Checking file integrity."
    #we are expecting a sha1 file with one line of content.
    #   this one line should look like:<file name>\t<sha1 sum>
    #we are exploding the expected content by " "
    #   first array entry is <file name>
    #   second array entry is \t
    #   third array entry is <sha1 sum>
    $expectedFileHash = $sha1FileContent.Split(" ")[2]

    If ($expectedFileHash -ne $calculatedFileHash.HASH) {
        Write-Host $("   Binary file integrity check failed. Expected checksum >>" + $expectedFileHash + "<<, current checksum >>" + $calculatedFileHash.HASH + "<<.")
    }
}

A bit more advanced script can be found here in my examples collection.

Translate to de es fr it pt ja

Create and manage a shadow copy snapshot for windows with powershell

Following my essence about the topic of creating a shadow copy snapshot.

#bo:create shadow copy
$shadowSourceVolume = ($env:SystemDrive + "\")
$shadowDestinationLinkPath = ($env:SystemDrive + "\shadowed_test")

#@see: https://docs.microsoft.com/en-us/previous-versions/windows/desktop/vsswmi/create-method-in-class-win32-shadowcopy#examples
$shadowCopyClass=[WMICLASS]"root\cimv2:win32_shadowcopy";

#create a shadow copy object
$shadowCopyObject = $shadowCopyClass.create($shadowSourceVolume, "ClientAccessible")
#fetch shadow object fron that
$shadowObject = Get-WmiObject Win32_ShadowCopy | Where-Object { $_.ID -eq $shadowCopyObject.ShadowID }
#fetch 
$shadowLinkPath = $shadowObject.DeviceObject + "\"
#eo:create shadow copy

#bo:create link
cmd /c mklink /d $shadowDestinationLinkPath $shadowLinkPath
#eo:create link

#bo: remove shadow link
cmd /c rmdir /S /Q $shadowDestinationLinkPath
#eo: remove shadow link

#bo: delete shadow copy
$shadowObject.Delete();
#Remove-CimInstance -InputObject $shadowObject
#eo: delete shadow copy

#bo: FTL
#list all available shadow copies
#Get-WmiObject Win32_Shadowcopy
#eo: FTL

Most important learned knowledge for me is that I only can create a snapshot of a whole volume.

Translate to de es fr it pt ja

Simple PowerShell Log Function

Just to share it somewhere with someone, following my powershell basic log function.

Function Log-Message {
    [cmdletbinding()]
    Param (
        [parameter(Mandatory=$true)] [string] $Message,
        [string] $LogLevel = "info"
    )

    $currentDate = Get-Date -Format "yyyyMMdd"
    $currentTime = Get-Date -Format "HHmmss"

    $logMessage = '{0} {1} [{2}]: {3}' -f $currentDate,$currentTime,$logLevel,$message

    $logMessage >> $logFile
}

Enjoy it.

Translate to de es fr it pt ja

Microsoft Powershells output is not local system language independet or - why "query user" sometimes returns USERNAME and BENUTZERNAME

I am working in an enviroment where some systems have a locale (or how microsoft is calling it "culture") of "en-US" or "de-DE".

Today I had to debug a script that is not outputting something. After a while, I've figured out that the result of query user /server:<server> is returning objects with different properties.

If the current locale is en-US, the property USERNAME exists. If the current locale is de-DE, the property BENUTZERNAME exists.

This is pretty sad since I could not find a way to set the culture within my powershell script to en-US.

What I've tried and what did not worked.

[System.Threading.Thread]::CurrentThread.CurrentCulture = "de-DE";
[System.Threading.Thread]::CurrentThread.CurrentUICulture = "de-DE";
[cultureinfo]::currentculture = 'de-DE';
[cultureinfo]::CurrentUICulture = 'de-DE';
Set-Culture de-DE

How did I solved it? I've added an or condition to support both properties, which is sad.

Where-Object { ($_.USERNAME -like "*$userNameToFilterAgainstOrNull*") -or ($_.BENUTZERNAME -like "*$userNameToFilterAgainstOrNull*") }

Good luck!

Translate to de es fr it pt ja