PowerShell Commands for Checking Windows Executable Properties
Inspecting Windows executable files (`.exe`) for their properties
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
Get-ItemProperty "path\to\file.exe"
Get File Name and Basic Info
Get-ItemProperty "path\to\file.exe" | Select-Object Name, Length, LastWriteTime
Version Information and Metadata
Get All Version Information
(Get-ItemProperty "path\to\file.exe").VersionInfo
Get Formatted Version Information
(Get-ItemProperty "path\to\file.exe").VersionInfo | Format-List
Get Specific Metadata Fields
(Get-ItemProperty "path\to\file.exe").VersionInfo | Select-Object ProductName, FileDescription, CompanyName, LegalCopyright
Get Key Application Metadata
(Get-ItemProperty "path\to\file.exe").VersionInfo | Select-Object ProductName, FileDescription, CompanyName, LegalCopyright, FileVersion, ProductVersion, OriginalFilename
Get All Metadata in Table Format
(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
(Get-ItemProperty "path\to\file.exe").VersionInfo | Select-Object IsDebug, IsPatched, IsPreRelease, IsPrivateBuild, IsSpecialBuild
Get Language and Culture Information
(Get-ItemProperty "path\to\file.exe").VersionInfo | Select-Object Language, FileVersionRaw, ProductVersionRaw
Get All Properties in Custom Format
$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:
# 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)
# 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
$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
$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
(Get-ItemProperty "*.exe").VersionInfo | Select-Object ProductName, CompanyName, FileVersion
Find Executables with Custom Icons (by size)
Get-ChildItem "dist" -Recurse -Filter "*.exe" | Where-Object { $_.Length -gt 50MB } | Select-Object Name, Length
Export Metadata to CSV
$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
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
Get-Acl "path\to\file.exe" | Select-Object Owner, AccessToString
Verify File is Not Corrupted
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
# 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
# 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
Recommended Articles

Bob's Basic Guide to Markdown
Markdown is a lightweight markup language used to format text. I'm using right now to write this basic examples of Markdown article. Let's get started with the basic examples of Markdown to showcase some of Markdown's features.

BJSL EULA v1
This is the first publicly released version of the Bob James Software Licence ("BJSL"), making our Software available free of charge for binary use and redistribution under the terms.