How To Execute Powershell Custom Actions in MSI using DLL

Written by Alex Marin · May 28th, 2021

Over the years, we've received many questions regarding how Custom Actions work with PowerShell scripts in MSI.

One of those questions is why we can access the PowerShell code in an MSI Project, but not in the resulting MSI when we open it.

In this article, we will explore how custom actions are executed in MSIs, what are the main custom action types and how PowerShell custom actions are interpreted differently from the rest within your MSI.

How Custom Actions Scripts Work in MSI?

The first thing we must take into consideration is to understand how scripts are executed in MSI technology. Unlike VBScript or JScript, PowerShell is not interpreted natively by the MSI.

The MSI knows how to trigger a custom action based on the custom action type. So, if you want to trigger a VBScript stored in the Binary table, the Custom Action type would be 6.

And, if you want to trigger a JScript file stored in the Binary table, the Custom Action Type would be 5.

NoteFor a full list of the custom action types, you can go review the Windows Documentation Scripts page.

However, you can use a workaround that Windows Installer editing tools added to include Powershell scripts with dynamic-link library (DLL) custom actions.

How does it work? When you build your MSI, the PowerShell code that was present in the project for your custom action gets added later in a DLL file. Then, the DLL file runs it -- and I will show you how in the following section.

How to Create PowerShell Custom Actions with Advanced Installer?

Advanced Installer gives you the possibility to run an Inline PowerShell Script or a PowerShell script from a file - the outcome is the same.

To get started, let’s create a project and navigate to the Custom Actions Page.

In this page, search for PowerShell and add the custom action of your choice, which in our case is “run Inline PowerShell Script”.

Once we build and install the package, the custom action will launch and the PowerShell code will be executed as intended. When we open up the project, we can see that the PowerShell code is stored in the project file.

But as we mentioned above, Powershell scripts are not interpreted natively, so if we were to edit the MSI file directly, the custom action will look completely different.

As you can see in the image below, the custom action is now a DLL file, where we have a function called RunPowerShellScript. The Action Data represents the PowerShell code stored inside the DLL file.

If we go even further in the Table Editor Page, we can see that a Binary for PowerShellScriptLauncher.dll was added in the MSI, and since we have the DLL stored in the binary table, the custom action type is 1:

Conclusion

We hope that this article brought some light on how custom actions are interpreted by the MSI, and how PowerShell custom actions must be included in the DLL file as a workaround since the PowerShell code cannot be interpreted from a MSI build.

Let us know if you have any other questions that you'd like us to respond to.

Comments: