All articles

PowerShell Commands for Checking Windows Executable Properties

Inspecting Windows executable files (`.exe`) for their properties

Bob⚡James
· 5 min read

This guide provides PowerShell commands to inspect Windows executable files (.exe) for their properties, metadata, icons, and other resources. These commands are particularly useful when working with Electron applications or any Windows software development where you need to verify that custom icons and metadata are correctly embedded.

Basic File Information

Get Basic File Properties

Shell
Get-ItemProperty "path\to\file.exe"

Get File Name and Basic Info

Shell
Get-ItemProperty "path\to\file.exe" | Select-Object Name, Length, LastWriteTime

Version Information and Metadata

Get All Version Information

Shell
(Get-ItemProperty "path\to\file.exe").VersionInfo

Get Formatted Version Information

Shell
(Get-ItemProperty "path\to\file.exe").VersionInfo | Format-List

Get Specific Metadata Fields

Shell
(Get-ItemProperty "path\to\file.exe").VersionInfo | Select-Object ProductName, FileDescription, CompanyName, LegalCopyright

Get Key Application Metadata

Shell
(Get-ItemProperty "path\to\file.exe").VersionInfo | Select-Object ProductName, FileDescription, CompanyName, LegalCopyright, FileVersion, ProductVersion, OriginalFilename

Get All Metadata in Table Format

Shell
(Get-ItemProperty "path\to\file.exe").VersionInfo | Select-Object ProductName, FileDescription, CompanyName, LegalCopyright, FileVersion, ProductVersion | Format-Table -AutoSize

Advanced Metadata Queries

Check if File is Signed

Shell
(Get-ItemProperty "path\to\file.exe").VersionInfo | Select-Object IsDebug, IsPatched, IsPreRelease, IsPrivateBuild, IsSpecialBuild

Get Language and Culture Information

Shell
(Get-ItemProperty "path\to\file.exe").VersionInfo | Select-Object Language, FileVersionRaw, ProductVersionRaw

Get All Properties in Custom Format

Shell
$file = Get-ItemProperty "path\to\file.exe"
$version = $file.VersionInfo

Write-Host "=== File Information ===" -ForegroundColor Green
Write-Host "File Name: $($file.Name)"
Write-Host "File Size: $([math]::Round($file.Length / 1MB, 2)) MB"
Write-Host "Last Modified: $($file.LastWriteTime)"
Write-Host ""
Write-Host "=== Application Metadata ===" -ForegroundColor Yellow
Write-Host "Product Name: $($version.ProductName)"
Write-Host "File Description: $($version.FileDescription)"
Write-Host "Company Name: $($version.CompanyName)"
Write-Host "Copyright: $($version.LegalCopyright)"
Write-Host "File Version: $($version.FileVersion)"
Write-Host "Product Version: $($version.ProductVersion)"

Icon and Visual Resources

Extract Icon Information (Requires Additional Tools)

While PowerShell doesn't have built-in icon extraction, you can check if an icon is present:

Shell
# Check file size - files with custom icons are typically larger
Get-ItemProperty "path\to\file.exe" | Select-Object Length

# Compare with default Electron executable size to see if icon was added

Using Windows API to Check Icon (Advanced)

Shell
# This requires .NET reflection to access Windows API
Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
using System.Drawing;

public class IconExtractor {
    [DllImport("shell32.dll")]
    public static extern IntPtr ExtractIcon(IntPtr hInst, string lpszExeFileName, int nIconIndex);
    
    [DllImport("user32.dll")]
    public static extern bool DestroyIcon(IntPtr hIcon);
}
"@

# Extract the main icon (index 0)
$iconHandle = [IconExtractor]::ExtractIcon([System.IntPtr]::Zero, "path\to\file.exe", 0)
if ($iconHandle -ne [System.IntPtr]::Zero) {
    Write-Host "Icon found in executable" -ForegroundColor Green
    [IconExtractor]::DestroyIcon($iconHandle)
} else {
    Write-Host "No icon found or default icon" -ForegroundColor Red
}

Batch Operations

Check Multiple Files

Shell
$files = @(
    "path\to\file.exe",
    "path\to\file2.exe"
)

foreach ($file in $files) {
    if (Test-Path $file) {
        Write-Host "=== $file ===" -ForegroundColor Cyan
        (Get-ItemProperty $file).VersionInfo | Select-Object ProductName, FileDescription, CompanyName | Format-List
        Write-Host ""
    } else {
        Write-Host "File not found: $file" -ForegroundColor Red
    }
}

Compare Two Executables

Shell
$file1 = "path\to\file-a.exe"
$file2 = "path\to\file-b.exe"

Write-Host "=== Comparing Executables ===" -ForegroundColor Magenta
Write-Host "Unpacked vs Installer" -ForegroundColor Yellow

$props = @('ProductName', 'FileDescription', 'CompanyName', 'LegalCopyright', 'FileVersion')

foreach ($prop in $props) {
    $val1 = (Get-ItemProperty $file1).VersionInfo.$prop
    $val2 = (Get-ItemProperty $file2).VersionInfo.$prop
    
    $status = if ($val1 -eq $val2) { "✓ MATCH" } else { "✗ DIFFERENT" }
    $color = if ($val1 -eq $val2) { "Green" } else { "Red" }
    
    Write-Host "$prop`: " -NoNewline
    Write-Host "$status" -ForegroundColor $color
    if ($val1 -ne $val2) {
        Write-Host "  Unpacked: $val1" -ForegroundColor Yellow
        Write-Host "  Installer: $val2" -ForegroundColor Yellow
    }
}

Useful One-Liners

Quick Metadata Check

Shell
(Get-ItemProperty "*.exe").VersionInfo | Select-Object ProductName, CompanyName, FileVersion

Find Executables with Custom Icons (by size)

Shell
Get-ChildItem "dist" -Recurse -Filter "*.exe" | Where-Object { $_.Length -gt 50MB } | Select-Object Name, Length

Export Metadata to CSV

Shell
$files = Get-ChildItem "dist" -Recurse -Filter "*.exe"
$results = foreach ($file in $files) {
    $version = (Get-ItemProperty $file.FullName).VersionInfo
    [PSCustomObject]@{
        FileName = $file.Name
        Path = $file.FullName
        ProductName = $version.ProductName
        FileDescription = $version.FileDescription
        CompanyName = $version.CompanyName
        FileVersion = $version.FileVersion
        Size = [math]::Round($file.Length / 1MB, 2)
    }
}
$results | Export-Csv "executable-metadata.csv" -NoTypeInformation
Write-Host "Exported metadata to executable-metadata.csv"

Troubleshooting Commands

Check if File is Accessible

Shell
if (Test-Path "path\to\file.exe") {
    Write-Host "File exists and is accessible" -ForegroundColor Green
} else {
    Write-Host "File not found or not accessible" -ForegroundColor Red
}

Check File Permissions

Shell
Get-Acl "path\to\file.exe" | Select-Object Owner, AccessToString

Verify File is Not Corrupted

Shell
try {
    $version = (Get-ItemProperty "path\to\file.exe").VersionInfo
    Write-Host "File is readable - ProductName: $($version.ProductName)" -ForegroundColor Green
} catch {
    Write-Host "File may be corrupted or locked: $($_.Exception.Message)" -ForegroundColor Red
}

Common Use Cases

Before and After Build Comparison

Shell
# Save metadata before applying fix
$beforeFix = (Get-ItemProperty "path\to\file.exe").VersionInfo
$beforeFix | Select-Object ProductName, FileDescription, CompanyName | Export-Clixml "before-fix.xml"

# After applying fix, compare
$afterFix = (Get-ItemProperty "path\to\file.exe").VersionInfo
$beforeData = Import-Clixml "before-fix.xml"

Write-Host "=== Before vs After Comparison ===" -ForegroundColor Magenta
Compare-Object $beforeData $afterFix -Property ProductName, FileDescription, CompanyName

Validate Build Output

Shell
# Check if all required metadata is present
$requiredFields = @('ProductName', 'FileDescription', 'CompanyName', 'LegalCopyright')
$version = (Get-ItemProperty "path\to\file.exe").VersionInfo

$missing = @()
foreach ($field in $requiredFields) {
    if ([string]::IsNullOrWhiteSpace($version.$field)) {
        $missing += $field
    }
}

if ($missing.Count -eq 0) {
    Write-Host "✓ All required metadata fields are present" -ForegroundColor Green
} else {
    Write-Host "✗ Missing metadata fields: $($missing -join ', ')" -ForegroundColor Red
}

Notes

  • Replace "path\to\file.exe" with your actual file path
  • Use quotes around paths that contain spaces
  • Some commands require elevated permissions if the executable is in a protected directory
  • File size comparisons can help identify whether custom icons were successfully embedded
  • The VersionInfo property contains all the metadata embedded in the executable's resources

Comments

Please sign in to leave a comment.

No comments yet. Be the first to comment!