89 lines
3.8 KiB
PowerShell
Executable File
89 lines
3.8 KiB
PowerShell
Executable File
<#
|
|
.SYNOPSIS
|
|
Lists executable files and drivers in a folder with metadata such as Company Name and Description.
|
|
.DESCRIPTION
|
|
Scans a directory for specified executable file types (.dll, .exe, .sys, etc.), retrieves
|
|
their version information, and outputs the results using strict UTF-8 encoding (WITHOUT BOM).
|
|
.PARAMETER Path
|
|
The target directory to scan. Defaults to the current working directory ($PWD).
|
|
.PARAMETER SortBy
|
|
The column to sort results by. Valid choices: Path, FileName, Modified, CompanyName, Description. Default is FileName.
|
|
.PARAMETER Descending
|
|
Sorts the output in descending order when specified.
|
|
.PARAMETER Recurse
|
|
Includes files in all subdirectories if specified.
|
|
.PARAMETER OutFile
|
|
Optional file path to save the formatted table output directly (UTF-8 without BOM).
|
|
.PARAMETER OutCSV
|
|
Optional file path to export the results directly to a CSV file (UTF-8 without BOM).
|
|
.PARAMETER Extensions
|
|
File extensions to search for. Accepts array or comma-separated strings (e.g. "dll, exe" or "*.sys").
|
|
.EXAMPLE
|
|
.\Get-FileInfo.ps1 -OutFile "output.txt"
|
|
Scans current directory and saves the formatted table directly to output.txt in UTF-8 without BOM.
|
|
.EXAMPLE
|
|
.\Get-FileInfo.ps1 "C:\Windows\System32" CompanyName -Recurse -OutCSV "C:\scan_results.csv"
|
|
Recursively scans System32, sorts by CompanyName, and exports to a CSV file without BOM.
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
param(
|
|
[Parameter(Position = 0)]
|
|
[string]$Path = $PWD,
|
|
|
|
[Parameter(Position = 1)]
|
|
[ValidateSet("Path", "FileName", "Modified", "CompanyName", "Description")]
|
|
[string]$SortBy = "FileName",
|
|
|
|
[switch]$Descending,
|
|
|
|
[switch]$Recurse,
|
|
|
|
[string]$OutFile,
|
|
|
|
[string]$OutCSV,
|
|
|
|
[string[]]$Extensions = @("*.dll", "*.exe", "*.sys", "*.ocx", "*.cpl", "*.drv", "*.ax", "*.mui", "*.scr")
|
|
)
|
|
|
|
# UTF-8 encoder explicitly configured to NOT emit BOM ($false)
|
|
$Utf8NoBom = New-Object System.Text.UTF8Encoding $false
|
|
$OutputEncoding = $Utf8NoBom
|
|
[Console]::OutputEncoding = $Utf8NoBom
|
|
|
|
# Append wildcard if non-recursive so -Include works properly
|
|
$SearchPath = if (-not $Recurse -and -not $Path.EndsWith('*')) { Join-Path $Path '*' } else { $Path }
|
|
|
|
# Clean, split, and normalize extensions
|
|
$FormattedExtensions = $Extensions | ForEach-Object { $_ -split ',' } | ForEach-Object {
|
|
$ext = $_.Trim()
|
|
if ($ext -and $ext -notlike "*.*") { "*.$ext" } else { $ext }
|
|
} | Where-Object { $_ }
|
|
|
|
$Results = Get-ChildItem -Path $SearchPath -Include $FormattedExtensions -File -Recurse:$Recurse -ErrorAction SilentlyContinue | ForEach-Object {
|
|
[PSCustomObject]@{
|
|
Path = $_.DirectoryName
|
|
FileName = $_.Name
|
|
Modified = $_.LastWriteTime
|
|
CompanyName = $_.VersionInfo.CompanyName
|
|
Description = $_.VersionInfo.FileDescription
|
|
}
|
|
} | Sort-Object -Property $SortBy -Descending:$Descending
|
|
|
|
# Export to CSV (UTF-8 No BOM)
|
|
if ($OutCSV) {
|
|
$ResolvedCsvPath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($OutCSV)
|
|
$CsvLines = $Results | ConvertTo-Csv -NoTypeInformation
|
|
[System.IO.File]::WriteAllLines($ResolvedCsvPath, $CsvLines, $Utf8NoBom)
|
|
Write-Host "Exported $($Results.Count) results to CSV: '$ResolvedCsvPath'" -ForegroundColor Green
|
|
}
|
|
|
|
# Output Table (Console or Text File UTF-8 No BOM)
|
|
if ($OutFile) {
|
|
$ResolvedOutFile = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($OutFile)
|
|
$TableText = ($Results | Format-Table -AutoSize | Out-String)
|
|
[System.IO.File]::WriteAllText($ResolvedOutFile, $TableText, $Utf8NoBom)
|
|
Write-Host "Exported $($Results.Count) results to file: '$ResolvedOutFile'" -ForegroundColor Green
|
|
} elseif (-not $OutCSV) {
|
|
$Results | Format-Table -AutoSize
|
|
} |