Skip to content

Add new additionalPowerShellLocations option#5484

Open
chawyehsu wants to merge 3 commits into
PowerShell:mainfrom
chawyehsu:push-sntxrqrrpznt
Open

Add new additionalPowerShellLocations option#5484
chawyehsu wants to merge 3 commits into
PowerShell:mainfrom
chawyehsu:push-sntxrqrrpznt

Conversation

@chawyehsu
Copy link
Copy Markdown

@chawyehsu chawyehsu commented Apr 30, 2026

PR Summary

Implement and close #5233

This PR attempts to add a better (cross-platform friendly) way to configure additional PowerShell paths.

Details

This implementaion is a little different from what I've proposed last year in #5233, the primary difference is instead of a default?: boolean field, a weight?: number is used to rank entries and select the best matching entry. Since we cannot restrict the default: true per platform to only one in the VS Code extension configuration, using weighted sorting allows us to achieve a similar purpose. Furthermore, the more specific platform field involving arch is used to specify the target host instead of os.

Backward Compatibility? Yes

While the old powerShellAdditionalExePaths and powerShellDefaultVersion stay unchanged and can still be used to define additional PowerShell paths, the new additionalPowerShellLocations is added to be mutually exclusive, which means when additionalPowerShellLocations is defined(non-empty), old options are ignored. This keeps settings non-conflicting: users pick one path (old or new), not both. Intuitive, simple and easy to understand.

Old options could be marked deprecated after a transition period.

PR Checklist

Note: Tick the boxes below that apply to this pull request by putting an x between the square brackets.
Please mark anything not applicable to this PR NA.

  • PR has a meaningful title
  • Summarized changes
  • PR has tests
  • This PR is ready to merge and is not work in progress
    • If the PR is work in progress, please add the prefix WIP: to the beginning of the title and remove the prefix when the PR is ready

Signed-off-by: Chawye Hsu <su+git@chawyehsu.com>
@chawyehsu chawyehsu marked this pull request as ready for review April 30, 2026 12:03
Copilot AI review requested due to automatic review settings April 30, 2026 12:03
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new cross-platform-friendly configuration option (powershell.additionalPowerShellLocations) to let users define additional PowerShell executables with per-platform (OS+arch) filtering and weighted ranking, integrating it into PowerShell discovery and the Session Menu flow.

Changes:

  • Added SupportedPlatform, IAdditionalPowerShellLocation, and getSupportedPlatform() plus a new enumeration path for additional locations in PowerShellExeFinder.
  • Updated SessionManager to prefer additionalPowerShellLocations over legacy settings and to adjust entry weight when switching via Session Menu.
  • Added unit tests for supported-platform mapping and additional-location filtering/sorting; added the new setting schema to package.json.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/platform.ts Introduces the new platform/arch mapping + additional-location enumeration and integrates it into PowerShell discovery.
src/session.ts Reads the new setting, uses it to derive the requested PowerShell, and updates weight on Session Menu selection.
test/core/platform.test.ts Adds coverage for platform mapping and additional-location filtering/priority behavior.
package.json Adds powershell.additionalPowerShellLocations configuration schema and documentation.

Comment thread src/platform.ts
Comment on lines +218 to +222
const configuredPowerShells =
this.additionalPowerShellLocations.length > 0
? this.enumerateAdditionalPowerShellLocations()
: this.enumerateAdditionalPowerShellInstallations();
for await (const additionalPwsh of configuredPowerShells) {
Comment thread src/session.ts Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@chawyehsu chawyehsu changed the title Add new additionalPowerShellLocations option WIP: Add new additionalPowerShellLocations option Apr 30, 2026
Signed-off-by: Chawye Hsu <su+git@chawyehsu.com>
@chawyehsu chawyehsu changed the title WIP: Add new additionalPowerShellLocations option Add new additionalPowerShellLocations option Apr 30, 2026
@chawyehsu
Copy link
Copy Markdown
Author

By any chance can I get some reviews? @JustinGrote @andyleejordan

Copy link
Copy Markdown
Member

@andyleejordan andyleejordan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just stopping by with a decision question: would there be a good way to handle the "default" cases of just windows/macos/linux (without architecture)? My thought is, and this is really an open question: are most people going to want or need to specify the architecture, especially as x64 is kinda on its way out (I mean look at macOS, you'd be hardpressed to find anything but Apple Silicon now). I'm thinking perhaps handle those as defaults, with architecture specific versions as options too.

On the note of these settings getting complicated, do we have a simpler way to handle "weight" that doesn't require the user to specify? I would think the ordered list of options would be implicit weights. Perhaps what this should be is three settings: Windows paths, macOS paths, Linux paths. Infer the priority from the order of paths in the list. Have an optional field on the subproperty (the required field being the path) that is the architecture. Eh?

@JustinGrote could you weigh in on this? Really just spitballing how to make this as clean of a user facing settings interface as possible.

@JustinGrote
Copy link
Copy Markdown
Collaborator

@andyleejordan @chawyehsu terminal profiles separate by OS.

I don't like the idea of hardcoding supported platforms. I don't see why this could just be a straight list of paths, and we simply test each path and if it doesn't exist, move on to the next. We would log at warning level paths that weren't found, but we wouldn't bubble up a notification box unless PowerShell couldn't be found at all.

My thoughts on the best design.

  1. If PowerShell Default Version is specified, search AdditionalExePaths that match that name, then autodiscover for that particular name, and if all that fails, typical discovery path. Possibly have a "strict" toggle that will show an error if that specific PowerShell Name cannot be found.

So for example, this config:

Name | Value
PowerShell | C:\MyCustomPs
PowerShell | /home/my/customps
PowerShellPreview | /home/my/preps

If nothing is specified for PowerShell default version, search all 3 of these paths first, in order, then autodiscover.

If 'PowerShell' is specified for default version:

  1. Search the first two paths first
  2. Autodiscover for "PowerShell" name (as opposed to winps or store)
  3. If the new "Strict PowerShell Default Version" is checked, throw an error saying not found at this point.
  4. If it is not checked, try remaining additionalexepaths in order, then autodiscover other powershells

We could do some basic path exclusions right off the bat based on Windows/NotWindows path styles, that way you can have a single consolidated list of all the paths you want to try that would be syncable cross platform.

This doesn't require two different config paths and keeps things simple.

@chawyehsu is there a scenario that the above would not address for you? Overrides can be done via profiles or remote development machine specific overrides like if you want preview to be default in a particular container, etc.

@andyleejordan
Copy link
Copy Markdown
Member

I don't like the idea of hardcoding supported platforms. I don't see why this could just be a straight list of paths, and we simply test each path and if it doesn't exist, move on to the next. We would log at warning level paths that weren't found, but we wouldn't bubble up a notification box unless PowerShell couldn't be found at all.

To my knowledge this is exactly how it works now (with the warnings able to be turned off because they're noisy).

@JustinGrote
Copy link
Copy Markdown
Collaborator

@andyleejordan I'll have to dive in but the nuance of how I mentioned how the priorities should work along with the "strict" checkbox is the net-new stuff, but the core UX would mostly stay the same.

@chawyehsu
Copy link
Copy Markdown
Author

My thought is, and this is really an open question: are most people going to want or need to specify the architecture, especially as x64 is kinda on its way out (I mean look at macOS, you'd be hardpressed to find anything but Apple Silicon now). I'm thinking perhaps handle those as defaults, with architecture specific versions as options too.

@andyleejordan When I first opened this PR, I considered only checking the OS without taking the architecture into account. For example, on Windows x64 you can still use the x86 version of PowerShell, and macOS is moving toward ARM-only anyway. However, I later changed the implementation to also check the architecture, mainly because of Linux: on Linux aarch64, you can't use the x64 build. The current SupportedPlatform logic is therefore based entirely on PowerShell's official support matrix. This is the closest match to PowerShell's release model that I could come up with. If there's a simpler approach, I'd be happy to go with it.

do we have a simpler way to handle "weight" that doesn't require the user to specify? I would think the ordered list of options would be implicit weights. Perhaps what this should be is three settings: Windows paths, macOS paths, Linux paths.

I did consider this method, but the merits of such implicit conventions are entirely subjective. One issue I find hard to agree with in this priority-by-ordering approach is that changing the default PowerShell via the bottom-right selector would end up reordering the entire configuration, causing much larger diffs in the settings file. In contrast, with the weight approach, the diff is limited to changes in the weight values only. And if entries for all platforms are mixed into a single ordering, it would become extremely messy.

terminal profiles separate by OS.

@JustinGrote I believe this link is irrelevant to the issue this PR seeks to address. Terminal profiles only affect the shell of the VS Code built-in terminal, while this discussion concerns the content within vscode-powershell that affects PowerShell selection and thus controls editor services such as LSP, if I understand correctly...

Name | Value
PowerShell | C:\MyCustomPs
PowerShell | /home/my/customps
PowerShellPreview | /home/my/preps

If nothing is specified for PowerShell default version, search all 3 of these paths first, in order, then autodiscover.

This is actually the existing configuration approach. However, it does not solve the issue mentioned in #5233. In case it's unclear, the problem in #5233 can actually be divided into two parts.

The first is the annoying warning, which can be resolved with the setting proposed by powershell.suppressAdditionalExeNotFoundWarning (thanks for pointing that out). The second is that the current powerShellAdditionalExePaths + powerShellDefaultVersion configuration model cannot specify different default PowerShell versions for different operating systems.

Here’s the scenario:

You can only set a single default version through powerShellDefaultVersion, and that value applies to all operating systems. For example, you cannot set PowerShell (Custom on Windows) as the default on Windows while using PowerShell (Custom on macOS) on macOS. The only option is to use something like PowerShell (Custom) as the universal default. But then you can no longer distinguish platforms by name, and you end up having to configure powerShellAdditionalExePaths like this:

"powershell.powerShellAdditionalExePaths": {
  "PowerShell (Custom)": "/opt/path/to/linux/bin/pwsh",
  "PowerShell (Custom)": "/opt/path/to/macos/bin/pwsh",
  "PowerShell (Custom)": "D:/PowerShell-custom/pwsh.exe"
}

(similar to what you mentioned above)

At first glance, this seems like it should work, i.e. VS Code would discover and use a different PowerShell (Custom) executable on each operating system. But it does not. The reason is that powerShellAdditionalExePaths is parsed as a hashmap. When multiple entries share the same key PowerShell (Custom), only the last one is retained and the others are overwritten.

As a result, on macOS/Linux, vscode-powershell ends up trying to discover D:/PowerShell-custom/pwsh.exe, fails, and then reports the following error:

I don't think you can solve this problem without getting rid of the current powerShellDefaultVersion configuration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Need a better (cross-platform friendly) way to configure additional PowerShell paths

4 participants