The term ‘{0}’ is not recognized as the name of a cmdlet, function, script file, or operable program.

Applicable to:PowerShell Core global tool 6.2.2 and 6.2.3.
TL;DR;For the purposes of defining scope, I’m limiting the following analysis to SDKs for .NET Core versions currently in LTS and versions in between. As of this writing, that would be 2.1. 2.2, 3.0 and 3.1.

This should work well enough for most cases:

– If you can root or sudo, install whatever version of PowerShell you deem appropriate with an installer or package manager depending on your operating system;
– Else, if you have .NET Core SDK 3.1, update to PowerShell Core tool 7.0.0;
– Else update to PowerShell Core global tool 6.2.4.

For details, read on…

As written in my the last post, installing PowerShell global tool 7.0 solved the issue of initializing PowerShell extension for Visual Studio Code (ms-vscode.powershell).

But there was one thing intriguing me: While trying to initialize the extension, some writing in red was flashing in Code’s integrated terminal.

After capturing it on video and pausing it at precisely the split second the message appears it is possible to read:

-NoProfile: The term '-NoProfile' is not recognized as the name of a cmdlet, funciton, script, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ -NoProfile -NonInteractive -EncodedCommand SQBtAHAAbwByAHQALQBNAG8AZA...
+ ~~~~~~~~~~
+ CategoryInfo          : ObjectNotFound: (-NoProfile:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException

Coincidentally, the parameters seen in the error message match those I had seen previously in the extension’s output log…

PowerShell Extension Output log

… from which I removed timestamps, log level, and truncated the log message for better display below:

Visual Studio Code v1.43.0 64-bit
 PowerShell Extension v2020.3.0
 Operating System: Linux 64-bit
 Language server starting --
     PowerShell executable: /home/alfred/.dotnet/tools/pwsh
     PowerShell args: -NoProfile -NonInteractive -Encoded...
     PowerShell Editor Services args: Import-Module '/home/...
 pwsh started.
 Waiting for session file
 Error occurred retrieving session file
 Language server startup failed.
 The language service could not be started: 
 Timed out waiting for session file to appear.

It is unfortunate that the extension’s log doesn’t show the same information that, albeit briefly, is shown in the integrated terminal – showing instead a misleading error due to some “session file”.

If we capture those parameters from the log and use them for running PowerShell directly, we’ll receive the same exact error shown in the integrated terminal.

With this we can discard ms-vscode.powershell as the source for the error and instead focus on pwsh itself.

It’s nice to see in practice the link of the failure in initializing the extension to the parsing of arguments in PowerShell Core global tool, but this doesn’t really add that much to the situation given I already had learned this is a known bug:

Older versions of the PowerShell dotnet global tool have a bug in them where arguments are not processed properly, breaking our startup invocation.

Please update your PowerShell version to 7 to enable this, or install a non-global tool PowerShell installation and configure the PowerShell extension to use it…

Although the statement pointed me in the right direction, it is imprecise and may lead some people, as was my case, to incorrect conclusions such as the only two alternatives being into install PowerShell global tool 7.0.0 or using some means of installation other than as a .NET Core tool.

Given I had very little exposure to PowerShell running on operating systems other than Windows and haven’t played at all with .NET Core tools, I took the opportunity to read through the documentation and do some testing. Here are some of my findings:

If you have root permissions or can sudo, you’re probably better off installing PowerShell using any means other than as a .NET global tool. PowerShell Core global tool can be seen as a shim over the “real thing”™, an extra layer that in versions 6.2.2 and 6.2.3 had it’s option parsing broken.

If you can’t sudo or elevate to root, you’ll have to resort to using .NET Core tools. First checkout what SDK versions are installed and confirm that PowerShell is installed as a .NET Core tool:

$ dotnet --list-sdks
 2.1.804 [/usr/share/dotnet/sdk]
 3.1.200 [/usr/share/dotnet/sdk]

$ dotnet tool list -g
 Package Id      Version      Commands
 powershell      6.2.3        pwsh   

Whichever SDK versions are installed, you can always uninstall a given version, then install another version. For instance:

# dotnet tool uninstall -g powershell
 Tool 'powershell' (version '6.2.3') was successfully uninstalled.

# dotnet tool install -g --version 6.2.4 powershell
 You can invoke the tool using the following command: pwsh
 Tool 'powershell' (version '6.2.4') was successfully installed.

But upgrading can be done in a single step using dotnet tool update:

# dotnet tool update -g powershell
 Tool 'powershell' was successfully updated from version '6.2.3' to version '7.0.0'.

The command above will work as long the latest version of the .NET Core tool on the package repository is compatible with the latest .NET Core SDK version installed locally.

Otherwise, it is necessary to specify the tool version, which can only be done starting with .NET Core SDK 3.0:

# dotnet tool update -g --version 6.2.4 powershell
 Tool 'powershell' was successfully updated from version '6.2.3' to version '6.2.4'.

The language service could not be started: Source: PowerShell (Extension)

Earlier today when opening a PowerShell script in Visual Studio Code I got the following error message:

The language service could not be started:

Source: PowerShell (Extension)

After some investigation that included changing the Editor Services log level to Diagnostic, and decoding the base64 encoded command being passed to pwsh, it was pointed out to me on GitHub that PowerShell versions prior to 7 contain a bug that, when they’re installed as a .NET Core global tool, prevents them from processing parameters passed to the pwsh command.

So just to confirm the version I had installed, I ran…

$ dotnet tool list -g

 Package Id      Version      Commands
 powershell      6.2.3        pwsh  

… and then after closing opened instances of Visual Studio Code, I updated PowerShell using .NET Core’s CLI:

$ dotnet tool update powershell -g

Tool 'powershell' was successfully updated from version '6.2.3' to version '7.0.0'.

In case you didn’t install PowerShell through .NET Core’s CLI, you may want to take a look at “Installing various versions of PowerShell” over on Microsoft Docs where you’ll find instructions for installing PowerShell on all the supported target platforms.

@id:ms-vscode.csharp – No extensions found.

There seems to have been a release coordination snafu between Visual Studio Code and the latest release for the C# for Visual Studio Code extension and as a result, you may be getting…

The ‘C#’ extension is recommended for this file type.

… over and over again.

If you click on Install, Code will tell you it can’t find the extension.

@id:ms-vscode.csharp

No extensions found.

The issue is caused by publisher for the extension being changed from ms-vscode to ms-dotnetools and how this cascades to other parts of the extension such as it’s Id.

From what I understood from the issue over on GitHub, the problem should go away with the next version of Visual Studio Code – the current version being 1.42.1.

$ code --version
 1.42.1
 c47d83b293181d9be64f27ff093689e8e7aed054
 x64

Meanwhile, since there are reports on GitHub about the change impacting dependent extensions, the workaround will depend on whether you use one of those extensions and how much the installation prompt bugs you.

A good start is finding out which extension, if any, you have installed.

$ code --list-extensions | grep -E 'ms-\w+.csharp'

This should return ms-vscode.csharp if you have the older extension or ms-dotnettools.csharp if you have the newer one. It may return other extensions as well if they happen to match the given regular expression.

If you have the newer version and are OK with being prompt to install it over and over again, you’re set up. Otherwise, you can still get the older version, but since it has been removed from the Marketplace, you’ll have to resort to getting it from GitHub.

$ code --uninstall-extension ms-dotnettools.csharp
 Uninstalling ms-dotnettools.csharp…
 Extension 'ms-dotnettools.csharp' was successfully uninstalled!

$ wget https://github.com/OmniSharp/omnisharp-vscode/releases/download/v1.21.12/csharp-1.21.12.vsix
...

$ code --install-extension csharp-1.21.12.vsix
Installing extensions…
 Extension 'csharp-1.21.12.vsix' was successfully installed.

How to copy Visual Code extensions to another machine

Earlier this month I was setting up an Ubuntu VM on Windows 10 for development and after installing Visual Studio Code it was time to install the extensions I’m used to having around.

There were 30 of them installed on my main development box. I probably don’t use most these of extensions, but I wasn’t in the mood to sort them out, so I searched for a way to export the settings so I could import them into Code running in the VM.

I wasn’t able to find what I was hoping for, the closest thing being the answers to “How can you export VS Code extension list” on StackOverflow.

# Based on the code snippet found at https://stackoverflow.com/a/49398449/151249
code --list-extensions | xargs -L 1 echo code --install-extension
view raw original-snippet.txt hosted with ❤ by GitHub

The answers were a step in the right direction but not quite where I ultimately wanted the solution to be:

  1. Having the list of extensions checked into source control with the rest of the project. For instance, if the team agreed on using ESLint as a build step, having a script to automate installing the corresponding extension (possibly one of many) could help in ramping up new project members.
  2. Having a way to sync extensions between machines or a way to export a list of extensions (not tied to any specific project) I could easily import to anywhere needed, such as disposable VMs, a new machine provided by an employer, etc.

I didn’t have time to figure out how to implement any of those ideas to the full extent of how I think they should work, but in the spirit of “Always Be Automating” I did the next best thing which was hacking a couple of one-liners, a step closer to the solution I want it to eventually be.

First I created a file containing the list of extensions:

code --list-extensions > vscode-extensions.txt
view raw export hosted with ❤ by GitHub

I think for most people the easiest way to access the list from other machines is putting the file somewhere online. I’m of the opinion that the best place to store anything development related is on GitHub, so I uploaded the list to a gist over there:

DavidAnson.vscode-markdownlint
docsmsft.docs-article-templates
docsmsft.docs-markdown
docsmsft.docs-preview
EditorConfig.EditorConfig
GitHub.vscode-pull-request-github
ms-azuretools.vscode-azureappservice
ms-azuretools.vscode-azurefunctions
ms-azuretools.vscode-azurestorage
ms-azuretools.vscode-cosmosdb
ms-mssql.mssql
ms-vscode.azure-account
ms-vscode.azurecli
ms-vscode.cpptools
ms-vscode.csharp
ms-vscode.mono-debug
ms-vscode.powershell
ms-vscode.vscode-node-azure-pack
ms-vsts.team
msazurermtools.azurerm-vscode-tools
msjsdiag.debugger-for-chrome
PeterJausovec.vscode-docker
redhat.java
VisualStudioExptTeam.vscodeintellicode
vsciot-vscode.azure-iot-toolkit
vscjava.vscode-java-debug
vscjava.vscode-java-dependency
vscjava.vscode-java-pack
vscjava.vscode-java-test
vscjava.vscode-maven

Then all I had to do to install those extensions was to CURL that file and pipe it into code:

#!/bin/bash
curl https://gist.githubusercontent.com/alfredmyers/336ed20410acee6688f7ba7c85b5826f/raw/84afcdbb919e9a9912c73914c7859746e862259a/vscode-extensions.txt | xargs -L 1 code --install-extension

That did the trick and I was able to continue working on whatever I was working on, although I wasn’t quite happy with the gist’s URL. See, I don’t know of anyway of getting rid of that automatically generated GUID which would make the URL more memorable.

Earlier today after watching Amanda Sliver and John Papa on Five Things, where she mentioned how to list Visual Studio Code extensions from the command-line, I decided to fix that URL problem putting the list on a GitHub repo with GitHub Pages turned on so instead of a cryptic URL I have something more memorable.

#!/bin/bash
curl https://alfredmyers.github.io/codex/all.txt | xargs -L 1 code --install-extension

I decided to call the repo Codex, for Code Extensions. That gives me an easy to remember base URL: https://alfredmyers.github.io/codex/

For now, I only have a single list in “all.txt”, but there’s nothing stopping me from creating other lists containing extensions for specific purposes or projects. For instance:

  • https://alfredmyers.github.io/codex/dotnet.txt
  • https://alfredmyers.github.io/codex/nojejs.txt

Oh… And by the way, once you CURL that list, you can pipe it into any command you’d like. For instance, to uninstall all those extensions we got from all.txt:

#!/bin/bash
curl https://alfredmyers.github.io/codex/all.txt | xargs -L 1 code --uninstall-extension

Just make sure you have a list of the extensions you really need hanging around so you can use it to reset everything to a desired state.

I you find the idea interesting, feel free to fork the project (https://github.com/alfredmyers/codex) and hack it to your needs. And don’t forget to turn on GitHub pages so you can access the lists using an easy to remember base URL such as https://{your-user-name}.github.io/codex/.

Cannot find runtime ‘node’ on PATH. Is ‘node’ installed?

On my current Windows box, I have Node.js installed only in WSL – not on Windows itself.

When debugging a Node.js application from within a Visual Studio Code instance started from WSL, you may receive the following message:

Cannot find runtime 'node' on PATH. Is 'node' installed?
Cannot find runtime ‘node’ on PATH. Is ‘node’ installed?

While the dev experience certainly could be better, the solution is quite simple: Click on the “Open launch.json” button and add a configuration for “useWSL” with the value set to “true”.

{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}\\entry-point.js",
"useWSL": true
}
]
}
view raw launch.json hosted with ❤ by GitHub