In enterprise endpoint administration and cybersecurity operations, verifying the authenticity and integrity of executable code is critical. Malicious software, tampered scripts, and trojanized dynamic link libraries (DLLs) frequently masquerade under legitimate filenames to evade detection. To protect systems from unverified code, Windows utilizes Microsoft Authenticode, a public-key cryptography standard that embeds digital signatures into Portable Executable (PE) binaries, PowerShell scripts, and catalog files.
Using PowerShell’s built-in Get-AuthenticodeSignature cmdlet, administrators and security analysts can inspect digital signature validity, audit certificate thumbprints, verify cryptographic hash integrity, and batch-audit folders for unsigned or tampered executables.
Inspecting Digital Signatures with Get-AuthenticodeSignature
To audit an executable file, open PowerShell and pass the target path to Get-AuthenticodeSignature:
Get-AuthenticodeSignature -FilePath "C:\Windows\System32\notepad.exe"
PowerShell returns a structured Signature object containing four primary properties:
- SignerCertificate: An
X509Certificate2object containing the digital certificate used to sign the file. - Status: The overall cryptographic validation result (e.g.,
Valid,NotSigned,HashMismatch,NotTrusted). - StatusMessage: A human-readable description explaining the status.
- Path: The absolute file path of the verified item.
Auditing Detailed Signer and Timestamp Certificates
Digital signatures often include an RFC 3161 cryptographic timestamp, ensuring that a binary remains valid even after the signer’s original code-signing certificate expires. To inspect detailed signer and timestamp metadata:
$sig = Get-AuthenticodeSignature -FilePath "C:\Windows\System32\cmd.exe"
# Inspect the signer certificate details
$sig.SignerCertificate | Select-Object Subject, Issuer, NotBefore, NotAfter, Thumbprint
# Inspect the timestamp authority details
$sig.TimeStamperCertificate | Select-Object Subject, Issuer, NotAfter
Understanding Verification Status Codes
The Status property reveals whether an executable can be trusted:
- Valid: The file’s hash matches the digital signature, and the signing certificate chains up to a trusted certificate authority in the Windows Trusted Root store.
- NotSigned: The file contains no embedded Authenticode signature or corresponding security catalog entry.
- HashMismatch: Critical warning. The file has been modified, tampered with, or corrupted after the digital signature was applied.
- NotTrusted: The file is signed, but the certificate chain terminates at an untrusted or self-signed Root CA not recognized by the operating system.
- UnknownError: Indicates severe file corruption, an unreadable header, or unsupported signature formatting.
Batch Scanning Directories for Unsigned Binaries
To identify unverified executables or scripts across administrative tool directories or download folders, pipe Get-ChildItem into Get-AuthenticodeSignature:
Get-ChildItem -Path "C:\Program Files\CustomTools" -Recurse -Include *.exe, *.dll, *.ps1 |
Get-AuthenticodeSignature |
Where-Object { $_.Status -ne "Valid" } |
Select-Object Status, StatusMessage, Path |
Format-Table -AutoSize
This command filters out all legitimate, verified files and reports only unsigned, corrupted, or untrusted items requiring investigation.
Signing Scripts with Set-AuthenticodeSignature
If your organization enforces strict execution policies (such as Set-ExecutionPolicy AllSigned), you can sign custom PowerShell scripts using a code-signing certificate installed in your user certificate store:
# Retrieve your code signing certificate
$cert = Get-ChildItem -Path Cert:\CurrentUser\My -CodeSigningCert | Select-Object -First 1
# Sign the script and apply a trusted timestamp
Set-AuthenticodeSignature -FilePath ".\Deploy-Workstation.ps1" -Certificate $cert -TimestampServer "http://timestamp.digicert.com"
Re-running Get-AuthenticodeSignature on the script confirms the status is now Valid, allowing safe execution across managed Windows 11 endpoints.