Public/Get-ApplicationSignatureAudit.ps1

using namespace System
using namespace System.IO
using namespace System.Security.Cryptography
using namespace System.Collections.Immutable

Set-StrictMode -Version Latest

#### <h2 style="color: #DCA657;">Get-ApplicationSignatureAudit</h2>
####
function Get-ApplicationSignatureAudit {
    #### Audit Authenticode signatures for every command visible on PATH.
    ####
    #### WindowsApps stubs are excluded. They are reparse points to packaged
    #### applications and report nothing useful about the binary behind them.
    ####
    #### <b style="color: #D2A8FF;">Parameters</b>
    ####
    [CmdletBinding()]
    [OutputType([PSCustomObject[]])]
    param(
        #### - `[int]`: __ThrottleLimit__
        #### - *Parallel throttle limit. Range 1 to 64. Defaults to 4.*
        [Parameter()]
        [ValidateRange(1, 64)]
        [int] $ThrottleLimit = 4
    )

    Get-Command -CommandType Application -All |
        Where-Object { $_.Source -notlike '*\AppData\Local\Microsoft\WindowsApps\*' } |
        ForEach-Object -Parallel {
            $cmd = $_
            try {
                $sig = Get-AuthenticodeSignature -FilePath $cmd.Source -ErrorAction Stop

                ####
                #### <b style="color: #369FFF;">Returns</b>
                ####
                #### - `[PSCustomObject[]]`
                #### - `[string]`: __Name__
                #### - *Command name.*
                #### - `[string]`: __Path__
                #### - *Absolute path to the executable.*
                #### - `[string]`: __Status__
                #### - *Signature status, for example `Valid`, `NotSigned`, or `Error`.*
                #### - `[string]`: __StatusMessage__
                #### - *Free form status text from the signature check.*
                #### - `[string]`: __SignerCertificate__
                #### - *Subject of the signer certificate, or `Unsigned`.*
                #### - `[string]`: __TimeStamper__
                #### - *Subject of the timestamp certificate, or `None`.*
                #### - `[bool]`: __IsOSBinary__
                #### - *True for a Microsoft signed operating system binary.*
                #### - `[string]`: __SignatureType__
                #### - *Signature type, for example `Authenticode`, `Catalog`, or `Unknown`.*
                [PSCustomObject]@{
                    Name              = $cmd.Name
                    Path              = $cmd.Source
                    Status            = $sig.Status.ToString()
                    StatusMessage     = $sig.StatusMessage
                    SignerCertificate = if ($sig.SignerCertificate) { $sig.SignerCertificate.Subject } else { 'Unsigned' }
                    TimeStamper       = if ($sig.TimeStamperCertificate) { $sig.TimeStamperCertificate.Subject } else { 'None' }
                    IsOSBinary        = $sig.IsOSBinary
                    SignatureType     = $sig.SignatureType.ToString()
                }
            }
            catch {
                #### A file that cannot be read still gets a row, with `Status` set to
                #### `Error` and the exception in `StatusMessage`. An audit that silently
                #### drops unreadable binaries reports a cleaner PATH than the one you have.
                [PSCustomObject]@{
                    Name              = $cmd.Name
                    Path              = $cmd.Source
                    Status            = 'Error'
                    StatusMessage     = $_.Exception.Message
                    SignerCertificate = 'Error'
                    TimeStamper       = 'None'
                    IsOSBinary        = $false
                    SignatureType     = 'Unknown'
                }
            }
        } -ThrottleLimit $ThrottleLimit
}
####
#### ---
####