The PowerShell Host With the Most

A host by any other name still smells as sweet. Now that I’ve thoroughly confused myself, I’ll move on to an oft-confusing topic for many users of PowerShell; PowerShell Hosts.

Over the years, I’ve seen a few posts on this topic. One of my favorites by Don Jones tries to help people understand how PowerShell works. It delves into why PowerShell may seem to behave differently when running from the regular PowerShell window, the PowerShell ISE, or even Visual Studio Code.

It all has to do with how we interact with PowerShell.

PowerShell Host vs. Shell

When I open up PowerShell or the PowerShell ISE, I am not directly interfacing with the PowerShell engine/shell itself. I am opening an application that hosts the PowerShell engine. This application host is what interacts with the PowerShell engine on my behalf and shuffles any commands that I type to the PowerShell engine to be executed.

Clear as mud, no?

Get-Host and $host

I can get more info about the current host by using either the Get-Host cmdlet or the built-in automatic variable $host.

Here is an example of running Get-Host with several common application hosts: PowerShell, PowerShell ISE, Visual Studio Code, and remote PowerShell:

Get-Host

Notice that the name changes between each host.

Regular PowerShell → ConsoleHost

PowerShell ISE → Windows PowerShell ISE Host

Visual Studio Code → Visual Studio Code Host

Remote PowerShell → ServerRemoteHost

Each of these different host applications implements the PowerShell engine a bit differently. Some notable differences between hosts are:

Automatic Variables

Automatic variables are defined by the application host. This includes the $host variable I spoke about a moment ago. This has already been pointed out above with the different names between each host.

Loaded .NET assemblies

The default set of loaded .NET assemblies is different depending on which host you’re using. I’m going to use the following command to demo that:

[System.AppDomain]::CurrentDomain.GetAssemblies()

Since I just want a count, I’ll modify my code to:

( [System.AppDomain]::CurrentDomain.GetAssemblies() ).count

Then, I’ll run it for each of my example hosts.

As you can see there are different assembly counts depending on which host I’m using.

Regular PowerShell → 22

PowerShell ISE → 51

Visual Studio Code → 42

Remote PowerShell → 18

Look at the differences! Be sure to test and verify before writing and implementing any scripts.

Colors

In the case of regular PowerShell and the PowerShell ISE, you can modify the colors via $host.PrivateData. For a peek into how that works, see my previous blog – Change the PowerShell Colors.

As for Visual Studio Code, there’s no data in $host.PrivateData to change since it’s all managed by Visual Studio Code itself.

Remote PowerShell host just uses the colors of the host that was used to establish the connection.

Profiles

Each host typically has two additional profiles that can be loaded when you start up the application. I can see the default profile for a given host by using the built-in automatic variable $profile.

For example, here is what I see in the regular PowerShell console:

$profile

There is a notable exception for the remote PowerShell host (ServerRemoteHost). This host does not have any $profiles that will execute.