【问题标题】:PowerShell - Get Properties of MSIPowerShell - 获取 MSI 的属性
【发布时间】:2022-12-14 05:39:44
【问题描述】:

堆垛机,

我正在尝试(从 Chrome Enterprise 的 MSI)获取版本号。在我将 Chrome 下载为 .MSI 之后,我注意到我可以看到许多属性。我希望能够访问并构建“if 语句”的是“评论”部分。

当我尝试使用 Get-Item 并将其格式化为列表时,它说那里什么都没有,我似乎无法确定要做什么。

(Get-Item ".\Chrome.msi").VersionInfo | fl

该命令返回:

如何从中提取“评论”部分和数据?

【问题讨论】:

标签: powershell windows-installer


【解决方案1】:

这些属性不存储在Get-ItemGet-Command 返回的System.IO.FileInfo 对象中。一种解决方案是使用 shell.application COM 对象为您检索这些属性:

$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,是您要查找的特定属性的 ID,因此在本例中为cmets.GetDetailsOf(.,.) 需要获取该信息。幸运的是,我之前也在尝试解析 cmets 时遇到过这个问题。我不记得在哪里但是,我找到了上面提出的解决方案,所以当我再次找到它时我会链接它。

【讨论】:

  • 有什么建议可以加快我对……所有此类内容的理解吗?有太多我不明白的地方……老实说,我只理解你发布的内容的一半,但你解决了我的问题并且成功了。太感谢了。
  • 如果您指的是 COM 对象,则可以将其视为某种管理类型的接口。在我们拥有 PowerShell 之前,我们拥有 COM 对象,它们让我们可以通过它们进入与操作系统相关的“东西”,并能够像您在上面看到的那样调用它们的方法(.NameSpace().ParseName 等)。为了更好地理解它们,它们实际上只是用于执行特定目的的函数。你指的是别的东西吗?
  • 啊,我明白了,谢谢;我指的是 COM 对象,但也只是……一切。我想如果我继续研究 PowerShell 和 Windows,我会学习所有这些(COM 对象、属性、get-member 等)。似乎有太多东西了,我可以学到的东西太深太广了哈哈……但我喜欢它。感谢您的帮助。
  • @BradyMigel,没问题的人。请记住,COM 对象不是 PowerShell 的本机对象,因此可能有一种更符合 PowerShell 惯用方式的方法来执行此操作,例如改为使用 .Net。 Get-Member 绝对是一个很好用的 cmdlet,祝你旅途愉快!
【解决方案2】:

您可以使用 Get-AppLockerFileInformation 获取 MSI 属性“ProductVersion”:

Get-AppLockerFileInformation -Path "C:PathTomy.msi" | Select -ExpandProperty Publisher | select BinaryVersion

仅当您的 MSI 已进行数字签名时,它才有效。

【讨论】:

    【解决方案3】:

    还有一个用于此的 PowerShell 模块。它易于安装、使用,并具有许多其他用于获取有关产品和补丁的信息的功能,并且可以安装、修改和卸载带有 PowerShell 进度的产品和补丁:

    Install-Module MSI
    Get-MSISummaryInfo <path>
    

    【讨论】:

    • 嗯,我想要这个版本:Get-MSIproperty productversion Box-x64.msi
    • 是的,它还有一个 Get-MSIProperty cmdlet。
    【解决方案4】:

    我的观点是从互联网上拼凑而成的。

    $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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-01
      • 2019-05-24
      • 2018-10-17
      • 1970-01-01
      • 2017-03-07
      • 1970-01-01
      • 2013-11-15
      • 1970-01-01
      相关资源
      最近更新 更多