The pwsh.exe process is the new name for PowerShell Core starting with version 6.0. The executable changed names from powershell.exe to pwsh.exe. Let’s take a look at this executable.

Index

Installing PowerShell 6.0

The best place to start is over on the Github.com page for PowerShell. Not only do they have installers for every supported operating system, they have a good getting started guide for anyone new to PowerShell.

After the install, the folder for it is added to the PATH environment variable.

    PS:> $env:path -split ';'

    C:\windows\system32
    C:\windows
    C:\windows\System32\WindowsPowerShell\v1.0\
    C:\Program Files\PowerShell\6.0.0\
    C:\Program Files\Microsoft VS Code\bin

You should be able to run pwsh from any run box or other shell window. You can even start it from a PowerShell 5.1 prompt.

Side by side with PS 5.1

PowerShell 6.0 does not replace PowerShell 5.1 on your system. Instead, they install side by side and both can exist on the same system.

It is worth pointing out that not only did the name of the executable change, but several of the folder locations have changed. Let’s take a look at some of those changes.

exe location

First is the install location for the executable.

  • PS 5.1: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
  • PS 6.0: C:\Program Files\PowerShell\6.0.0\pwsh.exe

The original PowerShell used a v1.0 folder but never changed it for future versions. The install location moved out of the C:\Windows\System32 folder and into c:\Program Files. All the names that were WindowsPowerShell are now PowerShell. You will see this in other places too.

Modules

A fresh install of PowerShell 6.0 will not have any of your modules loaded. This is because all the module install locations have changed.

    # PowerShell 5.1
    PS:> $env:PSModulePath -Split ';'

    C:\Users\kevmar\Documents\WindowsPowerShell\Modules
    C:\Program Files\WindowsPowerShell\Modules
    C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules


    # PowerShell 6.0
    PS:> $env:PSModulePath -Split ';'

    C:\Users\kevmar\Documents\PowerShell\Modules
    C:\Program Files\PowerShell\Modules
    c:\program files\powershell\6.0.0\Modules

In the list above, you can see all the module locations for my system for each version of PowerShell. Let’s take a closer look at the new 6.0 locations.

The first one C:\Users\$env:username\Documents\PowerShell\Modules is in my local profile. The folder name changed. Generally when I install modules, I load them in my local profile.

    Install-Module -Name PSGraph -Scope CurrentUser

The second one C:\Program Files\PowerShell\Modules is for all users of the system. If you are installing a module for everyone to use, it should be in this location. DSC will look here for modules when it is configuring a system. Again, we have a slight name change.

The third one c:\program files\powershell\6.0.0\Modules is for modules that are core to PowerShell itself. Generally this is a folder that you would not manage. If you need to add or update a module on your system, you will place it in one of the previous folders.

$PROFILE

PowerShell 6.0 has a new $PROFILE location for us to use.

  • PS 5.1: C:\Users\kevmar\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
  • PS 6.0: C:\Users\kevmar\Documents\PowerShell\Microsoft.PowerShell_profile.ps1

This is mostly due to the renaming of folder. If you do have important stuff in your profile, you will need to add it to your new profile location. Most people use the profile to set a custom prompt or import often used modules.

Command-line options

pwsh.exe is a standard console application and it has command line options available to us. I am going to list the important ones below, but you can run pwsh -? for the full list.

    PS:> pwsh -?

    Usage: pwsh[.exe] [[-File] <filePath> [args]]
                    [-Command { - | <script-block> [-args <arg-array>]
                                    | <string> [<CommandParameters>] } ]
                    [-ConfigurationName <string>] [-EncodedCommand <Base64EncodedCommand>]
                    [-ExecutionPolicy <ExecutionPolicy>] [-InputFormat {Text | XML}]
                    [-Interactive] [-NoExit] [-NoLogo] [-NonInteractive] [-NoProfile]
                    [-OutputFormat {Text | XML}] [-Version] [-WindowStyle <style>]

        pwsh[.exe] -h | -Help | -? | /?

    PowerShell Online Help https://aka.ms/pscore6-docs

    All parameters are case-insensitive.

    -Command | -c
        Executes the specified commands (and any parameters) as though they were typed
        at the PowerShell command prompt, and then exits, unless NoExit is specified.
        The value of Command can be "-", a string. or a script block.

        If the value of Command is "-", the command text is read from standard input.

        If the value of Command is a script block, the script block must be enclosed
        in braces ({}). You can specify a script block only when running 'pwsh'
        in a PowerShell session. The results of the script block are returned to the
        parent shell as deserialized XML objects, not live objects.

        If the value of Command is a string, Command must be the last parameter in the command,
        because any characters typed after the command are interpreted as the command arguments.

        To write a string that runs a PowerShell command, use the format:
        "& {<command>}"
        where the quotation marks indicate a string and the invoke operator (&)
        causes the command to be executed.

        Example:
            pwsh -Command {Get-WinEvent -LogName security}
            pwsh -command "& {Get-WinEvent -LogName security}"

    -EncodedCommand | -e | -ec
        Accepts a base64 encoded string version of a command. Use this parameter to submit
        commands to PowerShell that require complex quotation marks or curly braces.

        Example:
            $command = 'dir "c:\program files" '
            $bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
            $encodedCommand = [Convert]::ToBase64String($bytes)
            pwsh -encodedcommand $encodedCommand

    -ExecutionPolicy | -ex | -ep
        Sets the default execution policy for the current session and saves it
        in the $env:PSExecutionPolicyPreference environment variable.
        This parameter does not change the PowerShell execution policy
        that is set in the registry.

        Example: pwsh -ExecutionPolicy RemoteSigned

    -File | -f
        Default parameter if no parameters is present but any values is present in the command line.
        Runs the specified script in the local scope ("dot-sourced"), so that the functions
        and variables that the script creates are available in the current session.
        Enter the script file path and any parameters. File must be the last parameter
        in the command, because all characters typed after the File parameter name are interpreted
        as the script file path followed by the script parameters.

        Example: pwsh HelloWorld.ps1

    -Help | -h | -? | /?
        Shows this help message.

    -NoExit | -noe
        Does not exit after running startup commands.

        Example: pwsh -NoExit -Command Get-Date

    -NoLogo | -nol
        Hides the copyright banner at startup.

    -NonInteractive | -noni
        Does not present an interactive prompt to the user. Inverse for Interactive parameter.

    -NoProfile | -nop
        Does not load the PowerShell profiles.

    -Version | -v
        Shows the version of PowerShell and exits. Additional arguments are ignored.

        Example: pwsh -v

    -WindowStyle | -w
        Sets the window style to Normal, Minimized, Maximized or Hidden.

The good news here is that none of the common parameters have changed. In most cases, you can substitute the new pwsh.exe for the old powershell.exe in your scripts and scheduled tasks.

Why change the name to pwsh?

This is a valid question. Mark Kraus has a good post summarizing the details on his blog. You can read the discussion about the name change on Github.

Closing comments

I expect the name change will cause a little confusion for those that don’t work with PowerShell very closely. Someone is going to see pwsh.exe in task manager one day and wonder what it is. When that day comes, I hope they find this article helpful.