Reputation: 65
Stackers,
I am trying to get (from an MSI of Chrome Enterprise) a version number. After I download Chrome as a .MSI , I notice that I can see a number of properties. The one I want to be able to access and build an "if statement" off of is the "Comments" section.
When I try to use Get-Item and format it as a list, it says there is nothing in there and I cannot seem to identify what to do.
(Get-Item ".\Chrome.msi").VersionInfo | fl
That command returns:
How can I pull the "Comments" section and the data from it?
Upvotes: 6
Views: 14753
Reputation: 11
Powershell 3.0+
$wi = New-Object -Com WindowsInstaller.Installer
$wi.SummaryInformation("C:\PathTo\my.msi").Property(6)
Powershell 2.0
$WI = New-Object -ComObject WindowsInstaller.Installer
$SI = $WI.GetType().InvokeMember("SummaryInformation", "GetProperty", $null, $WI, @("C:\PathTo\my.msi"))
$SI.GetType().InvokeMember("Property", "GetProperty", $null, $SI, @(6))
6 = PID_COMMENTS
https://learn.microsoft.com/en-us/windows/win32/msi/summaryinfo-summaryinfo
Upvotes: 0
Reputation: 1
$msiFilePath = "C:\Path\To\Your\File.msi"
$shell = New-Object -ComObject Shell.Application
$folder = $shell.Namespace((Get-Item $msiFilePath).DirectoryName)
$file = $folder.ParseName((Get-Item $msiFilePath).Name)
$subject = $folder.GetDetailsOf($file, 24)
$versionRegex = "\d+(.\d+){2,3}"
$version = ($subject | Select-String -Pattern $versionRegex).Matches.Value
Write-Host "Version: $version"
Upvotes: 0
Reputation: 558
You can obtain the MSI Property "ProductVersion" with Get-AppLockerFileInformation :
Get-AppLockerFileInformation -Path "C:\PathTo\my.msi" | Select -ExpandProperty Publisher | select BinaryVersion
it works only if your MSI is digitally signed.
Upvotes: 5
Reputation: 3311
There's also a PowerShell module for this. It's easy to install, use, and has many other features for getting information about products and patches, and can install, modify, and uninstall products and patches with PowerShell progress:
Install-Module MSI
Get-MSISummaryInfo <path>
Upvotes: 3
Reputation: 821
My take that is cobbled together from the internet.
$msifile = 'C:\googlechromestandaloneenterprise64.msi'
function Which-MSIVersion {
<#
.SYNOPSIS
Function to Check Version of an MSI file.
.DESCRIPTION
Function to Check Version of an MSI file for comparision in other scripts.
Accepts path to single file.
.PARAMETER msifile
Specifies the path to MSI file.
.EXAMPLE
PS> Which-MSIVersion -msifile $msifile
68.213.49193
.NOTES
General notes
#>
param (
[Parameter(Mandatory = $true, HelpMessage = 'Specifies path to MSI file.')][ValidateScript({
if ($_.EndsWith('.msi')) {
$true
} else {
throw ("{0} must be an '*.msi' file." -f $_)
}
})]
[String[]] $msifile
)
$invokemethod = 'InvokeMethod'
try {
#calling com object
$FullPath = (Resolve-Path -Path $msifile).Path
$windowsInstaller = New-Object -ComObject WindowsInstaller.Installer
## opening database from file
$database = $windowsInstaller.GetType().InvokeMember(
'OpenDatabase', $invokemethod, $Null,
$windowsInstaller, @($FullPath, 0)
)
## select productversion from database
$q = "SELECT Value FROM Property WHERE Property = 'ProductVersion'"
$View = $database.GetType().InvokeMember(
'OpenView', $invokemethod, $Null, $database, ($q)
)
##execute
$View.GetType().InvokeMember('Execute', $invokemethod, $Null, $View, $Null)
## fetch
$record = $View.GetType().InvokeMember(
'Fetch', $invokemethod, $Null, $View, $Null
)
## write to variable
$productVersion = $record.GetType().InvokeMember(
'StringData', 'GetProperty', $Null, $record, 1
)
$View.GetType().InvokeMember('Close', $invokemethod, $Null, $View, $Null)
## return productversion
return $productVersion
}
catch {
throw 'Failed to get MSI file version the error was: {0}.' -f $_
}
}
Which-MSIVersion -msifile $msifile
Upvotes: 1
Reputation: 4694
These properties are not stored in the System.IO.FileInfo
object returned by Get-Item
or Get-Command
. A solution would be to use the shell.application
COM object to retrieve these attributes for you:
$filePath = ".\Chrome.msi"
$parentPath = (Resolve-Path -Path (Split-Path -Path $filePath)).Path
$fileName = Split-Path -Path $filePath -Leaf
$shell = New-Object -COMObject Shell.Application
$shellFolder = $Shell.NameSpace($parentPath)
$shellFile = $ShellFolder.ParseName($fileName)
$shellFolder.GetDetailsOf($shellFile,24)
24
, is the ID of the specific property you're after so in this case it's comments needed for .GetDetailsOf(.,.)
to get that info . Luckily, I came across this issue before when I too was trying to parse for the comments. I don't recall where but, I found the solution proposed above so I will link it when I can once again find it.
Upvotes: 8