Skip to main content

How to Verify a Digital Signature of an Executable in Batch Script

In an era of increasing cybersecurity threats, blindly executing files is a significant risk. Digital signatures allow you to verify that an executable (.exe or .msi) was actually created by the company claiming to have built it and, more importantly, that the file hasn't been tampered with since it was signed. Automating this verification in a Batch script is a critical step for secure deployment and malware prevention.

This guide will explain how to use a PowerShell wrapper within a Batch script to verify the digital signature of any file and make decisions based on its authenticity.

Why Verify Digital Signatures?

When you verify a signature, you are checking for two things:

  1. Authenticity: Was this really signed by Microsoft, Google, or your own organization?
  2. Integrity: Has the code been modified (e.g., by a virus or a hacker) after the signature was applied? If even a single byte of the file changes, the signature becomes invalid.

Method 1: Using the PowerShell "Get-AuthenticodeSignature" (No Downloads)

Every modern Windows system has PowerShell built-in. We can call its Get-AuthenticodeSignature cmdlet from a Batch file and check the "Status" property.

Verification Script:

@echo off
set "TargetFile=C:\Path\To\YourApp.exe"

if not exist "%TargetFile%" (
echo [ERROR] File not found: %TargetFile%
pause
exit /b 1
)

echo [VERIFY] Checking digital signature for: %TargetFile%...

:: Call PowerShell to check the signature status and display details
powershell -NoProfile -Command ^
"$sig = Get-AuthenticodeSignature -FilePath '%TargetFile%';" ^
"Write-Host 'Status:' $sig.Status;" ^
"if ($sig.SignerCertificate) {" ^
" Write-Host 'Signer:' $sig.SignerCertificate.Subject;" ^
" Write-Host 'Issuer:' $sig.SignerCertificate.Issuer;" ^
" Write-Host 'Expires:' $sig.SignerCertificate.NotAfter" ^
"};" ^
"if ($sig.Status -eq 'Valid') { exit 0 } else { exit 1 }"

if %errorlevel% equ 0 (
echo.
echo [SUCCESS] Digital signature is VALID and TRUSTED.
) else (
echo.
echo [CRITICAL] Digital signature is INVALID, EXPIRED, or UNTRUSTED!
echo Do not execute this file.
)

pause

Explanation of the Logic:

  1. Get-AuthenticodeSignature: This is the engine that checks the certificate chain.
  2. $sig.Status -eq 'Valid': We check if the status is exactly "Valid". Other statuses include NotSigned, HashMismatch, NotTrusted, or UnknownError.
  3. exit 0 / exit 1: PowerShell passes these exit codes back to the Batch %errorlevel%.

Method 2: Using Sysinternals "Sigcheck" (Professional Standard)

If you are a sysadmin, you might prefer the sigcheck utility from the Microsoft Sysinternals suite. It provides more detailed information, such as the signer's name and the timestamp.

@echo off
set "TargetFile=C:\Windows\System32\cmd.exe"

:: Assuming sigcheck.exe is in your script folder
set "sigcheck=%~dp0sigcheck.exe"

:: Verify sigcheck is available
if not exist "%sigcheck%" (
echo [ERROR] sigcheck.exe not found in: %~dp0
echo Download it from the Microsoft Sysinternals website.
pause
exit /b 1
)

echo [VERIFY] Checking signature for: %TargetFile%...
echo.

:: -q = Quiet (less verbose output)
:: -nobanner = Suppress the startup banner
"%sigcheck%" -q -nobanner "%TargetFile%"

echo.
if %errorlevel% equ 0 (
echo [SUCCESS] Signature is valid.
) else (
echo [ALERT] Signature check failed or file is unsigned.
)

pause
info

To check whether a certificate has been revoked (stolen or canceled), add the -r flag to your sigcheck command. This queries the Certificate Revocation List (CRL) online.

Best Practices and Security Rules

1. Always Check for "Valid" (not just "Signed")

A file can have a digital signature that is invalid. This happens if the file was modified after signing or if the certificate has expired. Never assume that the presence of a signature means the file is safe; only trust a signature that is Valid.

2. Handle Different Statuses

If the status is NotSigned, the file might still be safe (many open-source tools aren't signed), but you should treat it with extra caution. If the status is HashMismatch, the file has been altered and is almost certainly dangerous.

3. Absolute Paths

When passing file paths to PowerShell via a Batch script, always use absolute paths. If you use relative paths, PowerShell might look in an unexpected directory, leading to a "False Negative" result.

How to Avoid Common Errors

Wrong Way: Trusting the ErrorLevel purely from the command

Some commands return 0 if they "successfully finished checking," even if the signature they checked was invalid.

Correct Way: Explicitly tell PowerShell to exit with a non-zero code if the signature isn't valid, as shown in the Method 1 example.

Best Practice: Offline Verification

If your script runs on a computer with no internet access, the signature check might show as UnknownError because Windows cannot verify the certificate against an online authority.

:: For offline use, you might accept 'UnknownError' if you trust the local root CAs
powershell -NoProfile -Command ^
"$s = Get-AuthenticodeSignature -FilePath 'C:\Deploy\app.exe';" ^
"if ($s.Status -eq 'Valid' -or $s.Status -eq 'UnknownError') { exit 0 } else { exit 1 }"

Real-World Use Case: Secure Downloader

Imagine a script that downloads an update and only runs it if the signature is verified as valid.

@echo off
set "UpdateFile=%TEMP%\update.exe"

echo [DOWNLOAD] Fetching update...
:: (Download code here, e.g., curl, bitsadmin, or Invoke-WebRequest)

:: Verify the file was downloaded
if not exist "%UpdateFile%" (
echo [ERROR] Download failed. Update file not found.
pause
exit /b 1
)

echo [SECURITY] Verifying digital signature...

powershell -NoProfile -Command ^
"$s = Get-AuthenticodeSignature -FilePath '%UpdateFile%';" ^
"Write-Host 'Signature Status:' $s.Status;" ^
"if ($s.Status -ne 'Valid') { exit 1 }"

if %errorlevel% neq 0 (
echo [SECURITY ALERT] Update failed signature check! Deleting file...
del "%UpdateFile%" >nul 2>&1
pause
exit /b 1
)

echo [OK] Signature verified. Starting update...
start /wait "" "%UpdateFile%"

pause

Conclusions

Verifying digital signatures in Batch script is an essential component of a "Zero Trust" security model. By leveraging PowerShell's Get-AuthenticodeSignature or the industry-standard sigcheck, you can programmatically ensure that your systems only execute authentic, untampered code. This simple check is one of the most effective ways to block malware and unauthorized software modifications in professional environments.