Running powershell from windows right click

Hello to all,

Hope you can help me :slight_smile:

My goal is to get an msi product code as fast as possible.

So I found a powershell script that will do the job:

param([string]$MSIName)

# powershell.exe -file GetMSIProduct.ps1 -MSIName ApplicationName.msi

Function Get-MsiDatabaseProperties () {
<#
.SYNOPSIS
This function retrieves properties from a Windows Installer MSI database.
.DESCRIPTION
This function uses the WindowInstaller COM object to pull all values from the Property table from a MSI
.EXAMPLE
Get-MsiDatabaseProperties 'MSI_PATH'
.PARAMETER FilePath
The path to the MSI you'd like to query
#>
[CmdletBinding()]
param (
[Parameter(Mandatory=$True,
ValueFromPipeline=$True,
ValueFromPipelineByPropertyName=$True,
HelpMessage='What is the path of the MSI you would like to query?')]
[IO.FileInfo[]]$FilePath
)

begin {
$com_object = New-Object -com WindowsInstaller.Installer
}

process {
try {

$database = $com_object.GetType().InvokeMember(
"OpenDatabase",
"InvokeMethod",
$Null,
$com_object,
@($FilePath.FullName, 0)
)

$query = "SELECT * FROM Property"
$View = $database.GetType().InvokeMember(
"OpenView",
"InvokeMethod",
$Null,
$database,
($query)
)

$View.GetType().InvokeMember("Execute", "InvokeMethod", $Null, $View, $Null)

$record = $View.GetType().InvokeMember(
"Fetch",
"InvokeMethod",
$Null,
$View,
$Null
)

$msi_props = @{}
while ($null -ne $record) {
$prop_name = $record.GetType().InvokeMember("StringData", "GetProperty", $Null, $record, 1)
$prop_value = $record.GetType().InvokeMember("StringData", "GetProperty", $Null, $record, 2)
$msi_props[$prop_name] = $prop_value
$record = $View.GetType().InvokeMember(
"Fetch",
"InvokeMethod",
$Null,
$View,
$Null
)
}

$msi_props

} catch {
throw "Failed to get MSI file version the error was: {0}." -f $_
}
}
}


$MSIProperties = Get-MsiDatabaseProperties $MSIName
$MSIProperties.ProductCode

Next to it I add a new powershell script (run.ps1) that will run the first script:

powershell.exe C:\scripts\getcode.ps1 -MSINAME C:\scripts\example.msi | clip

So far so good. Every time I run the script I get the product code to clipboard.

Now I have created under Windows right click a new menu that run the run.ps1 and its also working.

What shell I do in order to get the product code of the msi file I am right clicking?

What should I write instead of absolute path c:\scripts\example.msi

Hope it was clear enough.
Thank you very much

Amir :slight_smile:

Create the context menu by modifying the registry to add a key with the name of the menu and and a sub-key for “command” with a command to launch your powershell script (wrapper) and use %1 as a placeholder for the file that was selected:

Key: Computer\HKEY_CLASSES_ROOT*\shell\OpenPS\command

Value: powershell C:\pathtoscript\run.ps1 %1

When you click on the new context menu it will launch your run.ps1 script and pass the full file path to run.ps1 as an argument.

 

Hi,

I did as you suggested, but seems that I am missing something.

the command under the registry is:
Powershell c:\scripts\run.ps1 %1

What I should fill in run.ps1 under the -path parameter?
$pc = c:\scripts\produtcode.ps1 -path “???” -property ProductCode
Write-Output $pc | clip

Thanks again

Amir

%1 is the placeholder for this argument in the command. I believe path was the only parameter so it is passing the argument positionally. “Path” will have the full path to the msi file when this command is ran.

Thank you very much

Work like a charm :slight_smile: