Font size: +

Reading Out An MSP Product Code With Powershell

Reading Out An MSP Product Code With Powershell

A Windows installer patch (MSP file) is a package file that contains updates for a certain application and describes which version of an application can be patched. The advantage of an MSP is that it contains only files that then become an MSI. MSPs are generally used for minor releases or small updates. I myself have a tool up my sleeve that can distribute binary differences for extremely small patches (to be released soon).
The patch contains, among other things, a product code and a patch code for the application to be changed. If the product code matches with the installed application, patching is possible. It is practical then to be able to determine this code before an installation in order to optimize a software distribution. I'll show you two solutions how to do so with PowerShell.
How do I find out the product code? One variant is found at Codeplex: MSI Powershell Module.

The disadvantage of this module is that you need to install an MSI for it, which further contains components of the Windows Installer XML. Thus nothing which can easily be packed into a package. Otherwise the MSI Powershell Module is excellent and I recommend it greatly for more complex things. After installing, one can determine the data of an MSI file like so:

get-msicomponentinfo `
    | where { $_.Path -like 'C:\Program Files\*\Common7\IDE\devenv.exe'} `
    | get-msiproductinfo

A short time ago I looked for another possibility to readout the product code of an MSP without the aforementioned overhead. The COM object “WindowsInstaller.Installer” offers this possibility. The advantage here is that this function can easily be used with an installation in order to determine if a system can be patched. In the near future I'll be incorporating this very thing into our Citrix XenDesktop patcher (http://www.software-virtualisierung.de/download/nitctxpatcher.html).

Readout of the “Display Name” of a patch with PowerShell. Note that not every MSP contains this:

 

function Get-MSPDisplayName {
<# 
.SYNOPSIS 
    Get the Display Name from an Microsoft Installer Patch MSP
.DESCRIPTION 
    Get Display Name from an Microsoft Installer Patch MSP (Andreas Nick 2015)
.NOTES 
    $NULL for an error
.LINK
.RETURNVALUE
  [String] Display Name
.PARAMETER
  [IO.FileInfo] Path to the msp file
#>
function Get-MSPDisplayName {
    param (
        [IO.FileInfo] $patchnamepath
    )
    try {
        $wi = New-Object -com WindowsInstaller.Installer
        $mspdb = $wi.GetType().InvokeMember("OpenDatabase", "InvokeMethod", $Null, $wi, $($patchnamepath.FullName, 32))
        $su = $mspdb.GetType().InvokeMember("SummaryInformation", "GetProperty", $Null, $mspdb, $Null)
        [String] $displayName = $su.GetType().InvokeMember("Property", "GetProperty", $Null, $su, 6)
        return $displayName
    }
    catch {
        Write-Output $_.Exception.Message
        return $NULL
    }
}

Readout of the Product Code of a Microsoft Patch (MSP) with PowerShell:

 

<# 
.SYNOPSIS 
    Get the Product Code from an Microsoft Installer Patch MSP
.DESCRIPTION 
    Get a Product Code from an Microsoft Installer Patch MSP (Andreas Nick 2015)
.NOTES 
    $NULL for an error
.LINK
.RETURNVALUE
  [String] Product Code
.PARAMETER
  [IO.FileInfo] Path to the msp file
#>
function Get-MSPProductcode {
    param (
        [IO.FileInfo] $patchnamepath
    )
    try {
        $wi = New-Object -com WindowsInstaller.Installer
        $mspdb = $wi.GetType().InvokeMember("OpenDatabase", "InvokeMethod", $Null, $wi, $($patchnamepath.FullName, 32))
        $su = $mspdb.GetType().InvokeMember("SummaryInformation", "GetProperty", $Null, $mspdb, $Null)
        #$pc = $su.GetType().InvokeMember("PropertyCount", "GetProperty", $Null, $su, $Null)
         
        [String] $productcode = $su.GetType().InvokeMember("Property", "GetProperty", $Null, $su, 7)
        return $productcode
    }
    catch {
        Write-Output $_.Exception.Message
        return $NULL
    }
}

Readout of the patch code of an MSP with PowerShell:

 

<# 
.SYNOPSIS 
    Get the Patch Code from an Microsoft Installer Patch MSP
.DESCRIPTION 
    Get a Patch Code from an Microsoft Installer Patch MSP (Andreas Nick 2015)
.NOTES 
    $NULL for an error
.LINK
.RETURNVALUE
  [String] Product Code
.PARAMETER
  [IO.FileInfo] Path to the msp file
#>
function Get-MSPPatchcode {
    param (
        [IO.FileInfo] $patchnamepath
         
    )
    try {
        $wi = New-Object -com WindowsInstaller.Installer
        $mspdb = $wi.GetType().InvokeMember("OpenDatabase", "InvokeMethod", $Null, $wi, $($patchnamepath.FullName, 32))
        $su = $mspdb.GetType().InvokeMember("SummaryInformation", "GetProperty", $Null, $mspdb, $Null)
        $pc = $su.GetType().InvokeMember("PropertyCount", "GetProperty", $Null, $su, $Null)
        #Write-Host $pc
        [String] $patchcode = $su.GetType().InvokeMember("Property", "GetProperty", $Null, $su, 9)
        return $patchcode
    }
    catch {
        Write-Output $_.Exception.Message
        return $NULL
    }
}

 

 

 

 

Folder2MSP, Patching Your Environment Couldn't Be ...
NITDedupBenchmark, a Test Tool for Storage Systems...
 

Comments

No comments made yet. Be the first to submit a comment
Already Registered? Login Here
Thursday, March 28, 2024

Captcha Image

@nickinformation Tweets

My german Blog: 

http://www.software-virtualisierung.de

in 

We use cookies on our website. Some of them are essential for the operation of the site, while others help us to improve this site and the user experience (tracking cookies). You can decide for yourself whether you want to allow cookies or not. Please note that if you reject them, you may not be able to use all the functionalities of the site.