Packaging scripts for PowerShell 7 and .NET Core

PrimalScript 7.6.143 was released on August 5th, 2020, and it includes support for PowerShell 7.0.3. We have started to support what was known as PowerShell Core with 7.0.0 and added debugging and packaging functionality for this new PowerShell version some time ago.
If you have used PrimalScript or PowerShell Studio before to work with Windows PowerShell, a few differences will stand out. I will try to explain the differences and point out some of the caveats and remedies needed to use this new PowerShell version.

1. PowerShell 7 is based on .NET Core.

This is an important difference to Windows PowerShell, which is based on the previous .NET framework. Packaging for Windows PowerShell produced a single executable with a .config file. Unless you needed other data files or supplemental scripts or executables, that was it.
Packaging for PowerShell 7 produces a folder with quite a number of files in it.

image

In .NET Core, just as it has been in MacOS, Linux, and other Unix derivatives for a long time, an application is not a single monolithic file. The folder containing the application file is considered the actual application. Please don’t think you can skip all the auxiliary files and just deploy the .exe; it won’t work.
I suggest you go and start packaging the scripts and additional files as an MSI to deploy your solutions if you have not done so already.

Because the folder is actually the application, you can no longer combine the files for multiple applications in one folder. You really need to keep the folders separate. Don’t try it; it just makes a mess of things.

image

2. PowerShell 7 binaries are not compatible with another.

This is not really a PowerShell problem but an effect of the differences between the .NET framework and .NET Core. Previously, if your application referenced an assembly, e.g., system.automation.dll, with a version 7.0.1 and you had 7.0.3 installed, that was perfectly fine.
Not so in .NET Core. The version numbers must be exactly matched. (Note: This may change as new versions are released).
What that means is that if you installed an application packaged for PowerShell 7.0.1 and then installed 7.0.3, your application no longer worked. This can, of course, be a huge problem for you. We will examine the remedy later.

3. The .NET Core philosophy is that an application, rather than relying on a specific runtime, should include all the required files within its application folder.

If you look at PowerShell 7’s installation folder, it does exactly that. That is great if you want to isolate your application for the ever-changing version mayhem of Windows updates and other application which may install, remove, or update the runtime components your application requires.
It costs more disk space since there is a lot of duplication, of course, but disk space is cheap.

image

If you have a single application or maybe even five, that is not so big of an impact. If you want to deploy dozens of little packaged utilities, it becomes a little ridiculous that each one would have to contain the entire Powershell install (roughly 220 MB or so) within it.
Remember that you cannot just mix the application folders together.

4. Microsoft’s release cycle is not supportable at this time.

PowerShell 7.0.3

07/16/2020

.NET Core 3.1.6

07/14/2020

PowerShell 7.0.2

06/11/2020

.NET Core 3.1.5

06/09/2020

.NET Core 3.1.4

05/19/2020

PowerShell 7.0.1

05/14/2020

.NET Core 3.1.3

03/24/2020

.NET Core 3.1.2

03/16/2020

PowerShell 7.0.0

03/04/2020

.NET Core 3.1.1

01/14/2020

Microsoft releases new versions of PowerShell 7 and the .NET Core framework at a breakneck speed. While Microsoft is interested in getting new features, bug fixes, and security patches out as fast as possible, it is impossible to adapt to new versions and release software fast enough to keep pace. For example, while we were working on supporting PowerShell 7.0.2 and investigating why the 32-bit debugging was broken, 7.0.3 was released, with 32-bit debugging still broken.
We also seriously doubt that any corporation or government entity will update its entire network to a new PowerShell version every month. Please let us know in the comments what your position on this is.

5. We have introduced the PowerShell 7.0.3 runtime install to keep your applications from breaking.

With this new PrimalScript build, a runtime installer can be found in the “Redistributable” folder. All PowerShell 7 applications packaged with this build will look for this runtime first before checking on a PowerShell 7 install folder.

image

This detaches your packaged PowerShell applications from the installed version. You can upgrade your computer’s PowerShell version individually or network-wide without affecting your deployed applications.
You can even deploy your PowerShell 7 applications with this runtime to computers that do not have PowerShell 7 installed at all.

So what is that “runtime”, you ask? We have simply taken PowerShell 7.0.3, removed the actual console, and created an installer for it. It is, in essence, PowerShell 7. You only need it once in the installed location, and then all packaged applications can reference it there. The install folder is version-specific; multiple runtimes can coexist, and, going forward, applications packaged for different versions will not interfere with one another.

6. Some things are currently disabled.

You will notice that 32-bit debugging for PowerShell 7 is currently still disabled. That is because .NET Core broke calling conventions for managed/unmanaged function calls. That is likely of little interest to you and does not affect 32-bit PowerShell 7 if that is what you are using, but it affects compiled C# applications like the debugger. We are monitoring new .NET Core versions and will issue updates as soon as we can.