Here’s a small chunk of code from a recent request asking how to write to the Windows Installer binary stream using Powershell:
$msiOpenDatabaseModeReadOnly = 0
$msiOpenDatabaseModeTransact = 1
$windowsInstaller = New-Object -ComObject windowsInstaller.Installer
$pathToMSI = "C:\Users\xxxx\Desktop\AlkaneExample.msi"
$database2 = $windowsInstaller.GetType().InvokeMember("OpenDatabase", "InvokeMethod", $null, $windowsInstaller, @($pathToMSI, $msiOpenDatabaseModeTransact))
$query = "INSERT INTO `Binary` (`Name`,`Data`) Values(?,?)"
$View = $database2.GetType().InvokeMember("OpenView","InvokeMethod",$Null,$database2,($query))
$binaryrecord = $windowsInstaller.GetType().InvokeMember("CreateRecord", "InvokeMethod", $null, $windowsInstaller, 2)
$binaryrecord.GetType().InvokeMember("StringData", "SetProperty", $null, $binaryrecord, @(1, "AlkaneBinary"))
$fileToStream = "C:\Alkane\AlkaneFile.txt"
$binaryrecord.GetType().InvokeMember("SetStream","InvokeMethod", $null, $binaryrecord, @(2, $fileToStream))
$View.GetType().InvokeMember("Execute", "InvokeMethod", $Null, $View, $binaryrecord)
$database2.GetType().InvokeMember("Commit", "InvokeMethod", $null, $database2, $null)
$View.GetType().InvokeMember("Close", "InvokeMethod", $Null, $View, $Null)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($View) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($binaryrecord) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($database2) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($windowsInstaller) | Out-Null