user8902801
user8902801

Reputation:

How gathering following output to a csv file

My script gathering msi information such as ProductCode, ProductName, Upgrade Code etc.. I am trying to get all information what in CLI read export a csv file.

Here is a piece of code, the rest is also similar

$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
}

Upvotes: 0

Views: 112

Answers (2)

The Fish
The Fish

Reputation: 1039

Graham's Answer is good. I had already started writing a function to export all the properties to PowerShell so decided to post it anyway.

I wrote a thing! It grabs all properties from an MSI and simply translates it into a PSCustomObject. This allows you to do a Select-Object on the object to grab the properties you're interested in.

$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

Hope it helps. Fish

Upvotes: 1

Graham J
Graham J

Reputation: 497

I had to do something fairly similiar myself, though only with a few select properties.

I used this microsoft site first of all to get a huge amount of data from the msi files.

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

Unfortunately the one property I needed wasn't listed, when my search continued I found this much simpler version of getting file info.

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

Armed with the second link I built a function to suit my needs perfectly - depending on the properties you're after this function can easily be amended, and once in an array it's easy to export.

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
}
}

Hope it helps

Upvotes: 2

Related Questions