Quickly switch between Windows PowerShell and PowerShell 6\7

What’s the difference between VS Code, Visual Studio, the PowerShell ISE, and PSScriptPad?

PowerShell Core 6 and 7 are the way forward for PowerShell. The PowerShell team is no longer investing in Windows PowerShell 5.1 or the PowerShell ISE. It’s recommended that you should upgrade to the newest versions to get new features. That said, many people are still using Windows PowerShell and the PowerShell ISE. In this post, we will look at how to use the PowerShell ISE with PowerShell Core 6 and 7.

Different Architectures

PowerShell 6\7 are built on .NET Core. Windows PowerShell is built on the .NET Framework. .NET Core is the cross-platform, cooler cousin of .NET Framework. Because of the difference in architecture, you won’t be able to load .NET Core assemblies (like PowerShell 6\7) into a .NET Framework process like the PowerShell ISE.

To learn more about the difference between .NET Core and .NET Framework, check out this article.

Local Remoting

Since there is the issue of different architectures, we need to start a new PowerShell process to actually host the PowerShell 6\7 runtime. We can then use remoting to connect to the pwsh.exe process. We can use the named pipe transport of PowerShell remoting to establish a connection to the remote process. Once the connection is established, we can push the runspace to the current host and execute commands against PowerShell 6 and 7 via the ISE.

An interesting side note is that a named pipe transport is also what you are using when you use the VS Code extension for PowerShell. It also starts an out-of-process pwsh.exe to execute the scripts and invoke IntelliSense. Albeit, VS Code uses a the language server protocol for the protocol while this technique uses the PowerShell Remoting protocol.

Step-by-step

The first step is to start a PowerShell 6 or 7 pwsh.exe process. Obviously, you’ll need PowerShell 6 or 7 installed.

Once the process is running, we will want to create a new out-of-process runspace that connects to the pwsh.exe process. You can use this simple function to establish a connection to that local process. To create a named pipe runspace, all you need to know is the process ID of the PowerShell.exe or Pwsh.exe process you want to connect to. You can then pass that process ID to the constructor for the NamedPipeConnectionInfo class.

The final step is to push the runspace variable as the current runspace within the ISE. This effectively establishes the runspace as the current runspace to use.

Now, we can execute PowerShell commands against the pwsh.exe process. If you run $PSVersionTable, you’ll see you are executing commands against PowerShell 6 or 7.

You’ll also notice that features such as IntelliSense are running against the PowerShell 6\7 process. As you can see here, Split-Path does not contain the parameter -LeafBase in Windows PowerShell.

In our augmented PowerShell ISE console, you’ll see that the Split-Path cmdlet does in fact contain the -LeafBase parameter that has been added in future versions.

Caveat

One problem is that the 1903 update of Windows broke the ISE’s ability to use the Out-Default cmdlet when using remoting. You’ll receive the error “Remote host method get_WindowSize is not implemented.”. To resolve this issue, you’ll need to override the Out-Default cmdlet. This can be done by using a steppable pipeline and Out-String.

PowerShell ISE Add-On Command

To make it easy to pop in and out of PowerShell 6\7 sessions, you can add a new command to the add-on menu and provide a key binding for easy switching between the two versions of PowerShell.

The final result is a quick switch between Windows PowerShell and PowerShell 6\7.

Looking to build Windows Forms in the ISE? Check out our previous post on how to do so.