Reputation: 27
I'm trying to extract some information from a MSI file like ProductCode
or CustomAction
. I've used other scripts from the internet and edited them, but my script has some issues.
This is only a little piece of the original code, but if I execute this, I get this error message:
WARNING: Exception calling "InvokeMember" with "5" argument(s): "OpenView,Sql"
function Get-MSIFileInformationList {
[CmdletBinding()]
[OutputType([string])]
param(
[parameter(Mandatory=$true,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true)]
[ValidateNotNullOrEmpty()]
[System.IO.FileInfo]$Path,
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$FROM = "Property",
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$LIKE = "Property",
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$WHERE = "Property",
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$SELECT = "Property"
)
Begin
{
}
Process {
try {
# Read property from MSI database
$WindowsInstaller = New-Object -ComObject WindowsInstaller.Installer
$MSIDatabase = $WindowsInstaller.GetType().InvokeMember("OpenDatabase", "InvokeMethod", $null, $WindowsInstaller, @($Path.FullName, 0))
$Query = "SELECT $SELECT FROM $FROM WHERE $WHERE LIKE '%$($LIKE)%'"
# $Query = "SELECT Value FROM CustomAction WHERE Action = '$($CustomAction)'"
Write-Host 1
$View = $MSIDatabase.GetType().InvokeMember("OpenView", "InvokeMethod", $null, $MSIDatabase, ($Query))
Write-Host 2
$View.GetType().InvokeMember("Execute", "InvokeMethod", $null, $View, $null) | Out-Null
Write-Host 3
$Record = $View.GetType().InvokeMember("Fetch", "InvokeMethod", $null, $View, $null)
try {
Write-Host 4
$Value = $Record.GetType().InvokeMember("StringData", "GetProperty", $null, $Record, 1)
Write-Host 5
# Commit database and close view
$MSIDatabase.GetType().InvokeMember("Commit", "InvokeMethod", $null, $MSIDatabase, $null) | Out-Null
Write-Host 6
$View.GetType().InvokeMember("Close", "InvokeMethod", $null, $View, $null) | Out-Null
Write-Host 7
$MSIDatabase = $null
$View = $null
} catch {
$Value = "-"
}
# Return the value
return $Value
}
catch {
Write-Warning -Message $_.Exception.Message ; break
return ""
}
}
End {
# Run garbage collection and release ComObject [System.Runtime.Interopservices.Marshal]::ReleaseComObject($WindowsInstaller) | Out-Null
[System.GC]::Collect()
}
}
Upvotes: 1
Views: 1701
Reputation: 54971
MSI-databases doesn't support LIKE
as it only implements a subset of the SQL-Language (https://msdn.microsoft.com/en-us/library/windows/desktop/aa372021.aspx). This should work:
$Query = "SELECT $SELECT FROM $FROM WHERE $WHERE = 'ProductName'"
If you need to filter, you would have to do it on the results of SELECT * FROM Property
.
Upvotes: 2