【问题标题】:How gathering following output to a csv file如何将以下输出收集到 csv 文件
【发布时间】:2019-11-04 01:29:10
【问题描述】:

我的脚本收集 msi 信息,例如 ProductCode、ProductName、升级代码等。 我正在尝试获取 CLI 中读取导出 csv 文件的所有信息。

这里是一段代码,其余的也差不多

$Dir =  Get-ChildItem -Path W:\MSIs\*.msi -Recurse

foreach ($item in $Dir) { 

try {
    $windowsInstaller = New-Object -com WindowsInstaller.Installer

    $database = $windowsInstaller.GetType().InvokeMember('OpenDatabase', 'InvokeMethod', $null, $windowsInstaller, @((Get-Item -Path $item).FullName, 0))

    $view = $database.GetType().InvokeMember('OpenView', 'InvokeMethod', $null, $database, ("SELECT Value FROM Property WHERE Property = 'ProductName'"))
    $view.GetType().InvokeMember('Execute', 'InvokeMethod', $null, $view, $null)

    $record = $view.GetType().InvokeMember('Fetch', 'InvokeMethod', $null, $view, $null)

   echo "Product Name"
    Write-Output -InputObject $($record.GetType().InvokeMember('StringData', 'GetProperty', $null, $record, 1))

} catch {
    Write-Error -Message "Product Name" $_.ToString()s

    break
}

【问题讨论】:

  • 我试过这样的事情,但它不能正常工作 Get-Process | Select-Object -Property ProductName、ProductCode、ProductVersion、UpgradeCode、Manufacturer | Export-Csv -Path Import-Csv -NoTypeInformation
  • 一点提示:如果您将其他信息(例如您迄今为止尝试过的内容)直接添加到问题中并进行编辑,它会更好,更具可读性。只要问题不变。
  • 您应该提供一个示例,说明您希望生成的 CSV 的外观,或者架构的结构。在上面的代码示例中,我看到许多语法错误和管道问题,使我无法理解您想要完成的工作。
  • 你不会得到ProductName, ProductCode, ProductVersion, UpgradeCode, Manufacturer,因为你在这里只选择了ProductNameSELECT Value FROM Property WHERE Property = 'ProductName'

标签: powershell csv export-to-csv


【解决方案1】:

我必须自己做一些非常相似的事情,尽管只有几个选择的属性。

我首先使用这个 microsoft 站点从 msi 文件中获取大量数据。

https://gallery.technet.microsoft.com/scriptcenter/Get-all-native-properties-e4e19180

不幸的是,我需要的一个属性没有列出,当我继续搜索时,我发现了这个更简单的获取文件信息的版本。

https://devblogs.microsoft.com/scripting/hey-scripting-guy-how-can-i-retrieve-the-subject-property-for-a-msi-file/

借助第二个链接,我构建了一个完全满足我需求的函数 - 取决于您在此函数之后的属性,可以轻松修改此函数,并且一旦进入数组就可以轻松导出。

Function Get-FileInfo {

<#
    .SYNOPSIS
    Retrieves information from files

    .DESCRIPTION 
    This function uses the WindowInstaller COM object to pull the subject line from an MSI file.

    .EXAMPLE
    Get-FileInfo E:\DownloadDir\MicrosoftIdentityExtensions-64.msi
    Name                        RevNo                                  Size
    ----                        -----                                  ----
    ACS S2S OAuth JWT Extension {6520558F-956F-4388-8C50-58E5557D7519} 252

    .NOTES
    Inspired by this:
    https://devblogs.microsoft.com/scripting/hey-scripting-guy-how-can-i-retrieve-the-subject-property-for-a-msi-file/

#>

Param (
    [parameter( Mandatory = $true ) ][ValidateNotNullOrEmpty()][System.IO.FileInfo]$FilePath
)

Begin {
    If ( $FilePath.Extension -match ".msi" ){
        $com_object    = New-Object -com WindowsInstaller.Installer
        $comproperties = $com_object.SummaryInformation( $FilePath.Fullname )
    }
    $msiproperties = @()
}

Process {
    If ( $FilePath.Extension -match ".msi" ){
        $msiproperties += [PSCustomObject] @{ 
            Name     = ( $comproperties.Property( 3 ) ).TrimEnd() ;
            RevNo    = $comproperties.Property( 9 );
            Creation = $comproperties.Property( 12 );
        }
    }

}

End { 
    Return $msiproperties
}
}

希望对你有帮助

【讨论】:

    【解决方案2】:

    格雷厄姆的回答很好。我已经开始编写一个函数来将所有属性导出到 PowerShell,所以还是决定发布它。

    我写了一个东西!它从 MSI 中获取所有属性并将其简单地转换为 PSCustomObject。这允许您在对象上执行 Select-Object 以获取您感兴趣的属性。

    $Dir =  Get-ChildItem -Path C:\MSIs\*.msi -Recurse
    
    function Get-MsiPropertyList  {
        [CmdletBinding()]
        param(
            [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
            [string]
            $Path
        )
    
        process {
            $Path | Foreach-Object {
                $item = $_
                $windowsInstaller = New-Object -ComObject WindowsInstaller.Installer
                $database = $windowsInstaller.GetType().InvokeMember('OpenDatabase', 'InvokeMethod', $null, $windowsInstaller, @((Get-Item -Path $item).FullName, 0))
    
                $view = $Database.GetType().InvokeMember('OpenView', 'InvokeMethod', $null, $Database, ("SELECT Property,Value FROM Property"))
                $view.GetType().InvokeMember('Execute', 'InvokeMethod', $null, $view, $null) | Out-Null
                $record = $view.GetType().InvokeMember('Fetch', 'InvokeMethod', $null, $view, $null)
    
                $ret = [pscustomobject]@{
                    Path = $item
                }
    
                while ($record -ne $null) {
                    $property = $record.GetType().InvokeMember('StringData', 'GetProperty', $null, $record, 1)
                    $value = $record.GetType().InvokeMember('StringData', 'GetProperty', $null, $record, 2)        
    
                    $ret | Add-Member -MemberType NoteProperty -Name $property -Value $value
    
                    $record = $view.GetType().InvokeMember('Fetch', 'InvokeMethod', $null, $view, $null)
                }
    
                Write-Output $ret
            }
        }
    }
    
    # Export all properties to a csv
    $Dir | Get-MsiPropertyList | Export-Csv -Path C:\MSIs\test.csv -NoTypeInformation
    
    # Export selected properties to a csv
    $Dir | Get-MsiPropertyList | Select-Object -Property Path, ProductName, ProductVersion | Export-Csv -Path C:\MSIs\test2.csv -NoTypeInformation
    

    希望对您有所帮助。 鱼

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-03
      • 2019-12-25
      • 1970-01-01
      • 1970-01-01
      • 2018-08-13
      • 1970-01-01
      • 2015-05-25
      • 2010-11-12
      相关资源
      最近更新 更多