Powershell获取MSI信息

时间:2017-04-03 13:29:23

标签: powershell windows-installer

我尝试从ProductCodeCustomAction等MSI文件中提取一些信息。我已经使用了互联网上的其他脚本并对其进行了编辑,但我的脚本存在一些问题。

这只是原始代码的一小部分,但如果我执行此代码,则会收到以下错误消息:

  

警告:异常调用" InvokeMember"用" 5"参数:" 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()
}
}

1 个答案:

答案 0 :(得分:2)

MSI数据库不支持LIKE,因为它只实现了SQL语言的一个子集(https://msdn.microsoft.com/en-us/library/windows/desktop/aa372021.aspx)。这应该有效:

$Query = "SELECT $SELECT FROM $FROM WHERE $WHERE = 'ProductName'"

如果您需要过滤,则必须对SELECT * FROM Property的结果进行过滤。