old.ironmansoftware.
com
Using PowerShell 7 in the Windows
PowerShell ISE
9-11 minutes
Images are still loading. Please cancel your print and try again.
Skip to content
Ironman Software Logo
Using PowerShell 7 in the Windows PowerShell ISE
Using PowerShell 7 in the Windows PowerShell ISE
PowerShell 7 is 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 7.
PowerShell Universal brings together the best of Universal
Automation and Dashboard. Build dashboards, execute
scripts, and schedule jobs with the tool built for PowerShell.
Different Architectures
PowerShell 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 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 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 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 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 7 pwsh.exe process.
Obviously, you’ll need PowerShell 6 or 7 installed.
$Process = Start-Process PWSH -ArgumentList @("-NoExit")
-PassThru -WindowStyle Hidden
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.
function New-OutOfProcRunspace {
param($ProcessId)
$ci = New-Object -TypeName
System.Management.Automation.Runspaces.NamedPipeConnectionInfo
-ArgumentList @($ProcessId)
$tt = [System.Management.Automation.Runspaces.TypeTable]::LoadDefaultTypeFiles()
$Runspace =
[System.Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace(
$Host, $tt)
$Runspace.Open()
$Runspace
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.
$Host.PushRunspace($Runspace)
Now, we can execute PowerShell commands against the pwsh.exe
process. If you run $PSVersionTable, you’ll see you are executing
commands against PowerShell 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
NOTE: This appears not longer to be necessary with PS7
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.
function Out-Default
param(
[switch]
$Transcript,
[Parameter(ValueFromPipeline=$true)]
[psobject]
$InputObject
begin
$pipeline = { Microsoft.PowerShell.Core\Out-Default
@PSBoundParameters
}.GetSteppablePipeline($myInvocation.CommandOrigin)
$pipeline.Begin($PSCmdlet)
$Arr = @()
process
{
$pipeline.Process($_)
$Arr += $_
end
$pipeline.End()
$Arr | Out-String
Looking for an alternative to the ISE and VS Code with a form
designer and PS7 support? Check out PSScriptPad
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.
$psISE.CurrentPowerShellTab.AddOnsMenu.Submenus.Clear()
$psISE.CurrentPowerShellTab.AddOnsMenu.Submenus.Add("Switch to PowerShell 7
{
function New-OutOfProcRunspace {
param($ProcessId)
$ci = New-Object -TypeName
System.Management.Automation.Runspaces.NamedPipeConnectionInfo
-ArgumentList @($ProcessId)
$tt = [System.Management.Automation.Runspaces.TypeTable]::LoadDefaultTypeFiles()
$Runspace =
[System.Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace(
$Host, $tt)
$Runspace.Open()
$Runspace
$PowerShell = Start-Process PWSH -ArgumentList @("-NoExit") -PassThru
-WindowStyle Hidden
$Runspace = New-OutOfProcRunspace -ProcessId $PowerShell.Id
$Host.PushRunspace($Runspace)
}, "ALT+F5") | Out-Null
$psISE.CurrentPowerShellTab.AddOnsMenu.Submenus.Add("Switch to Windows
PowerShell", {
$Host.PopRunspace()
$Child = Get-CimInstance -ClassName win32_process | where {$_.ParentProcessId
-eq $Pid}
$Child | ForEach-Object { Stop-Process -Id $_.ProcessId }
}, "ALT+F6") | Out-Null
The final result is a quick switch between Windows PowerShell and
PowerShell 7.
Looking to build Windows Forms in the ISE? Check out our
previous post on how to do so.
Related
About the Author: adam
Related Posts