Vaporup.Tools.psm1
|
function Get-MsiMetadata { <# .SYNOPSIS Extracts metadata and product properties from MSI files in a specified folder. .DESCRIPTION Scans a directory for .msi files and reads internal database properties including Product Name, Version, Manufacturer, Product Code (GUID), and Upgrade Code. .PARAMETER Path The directory containing the MSI files. Defaults to the current directory if omitted. .EXAMPLE Get-MsiMetadata -Path "C:\Installers" .EXAMPLE Get-MsiMetadata #> [CmdletBinding()] param( [Parameter(Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [ValidateScript({ Test-Path $_ -PathType Container })] [string]$Path = $PWD ) begin { # Initialize the Windows Installer COM object once try { $installer = New-Object -ComObject WindowsInstaller.Installer } catch { Write-Error "Failed to create Windows Installer COM object: $_" return } $propertiesToExtract = @('ProductName', 'ProductVersion', 'Manufacturer', 'ProductCode', 'UpgradeCode') } process { $resolvedPath = Resolve-Path -Path $Path Get-ChildItem -Path $resolvedPath -Filter "*.msi" | ForEach-Object { $msiFile = $_ $msiData = [ordered]@{ FileName = $msiFile.Name FullPath = $msiFile.FullName } $database = $null $view = $null try { # Open the database for read-only access (Mode 0) $database = $installer.OpenDatabase($msiFile.FullName, 0) foreach ($prop in $propertiesToExtract) { $view = $database.OpenView("SELECT Value FROM Property WHERE Property = '$prop'") $view.Execute() $record = $view.Fetch() if ($record) { $msiData[$prop] = $record.StringData(1) } else { $msiData[$prop] = "N/A" } if ($view) { [System.Runtime.InteropServices.Marshal]::ReleaseComObject($view) | Out-Null $view = $null } } [PSCustomObject]$msiData } catch { Write-Warning "Could not read metadata from $($msiFile.Name): $_" } finally { # Clean up COM references per file if ($view) { [System.Runtime.InteropServices.Marshal]::ReleaseComObject($view) | Out-Null } if ($database) { [System.Runtime.InteropServices.Marshal]::ReleaseComObject($database) | Out-Null } } } } end { if ($installer) { [System.Runtime.InteropServices.Marshal]::ReleaseComObject($installer) | Out-Null } } } |