Cli: [QUESTION] Necessity of Powershell Script Support for Global Packages

Created on 11 Nov 2019  ·  13Comments  ·  Source: npm/cli

What / Why


As per https://github.com/npm/read-cmd-shim/pull/6 adds PowerShell Scripts when installing global packages. It causes some hassle on Windows needing to add a security flag to run ps1 script, else it gets this error

**.ps1 cannot be loaded because running scripts is disabled on this system

Previously, all global npm packages run out of box as PowerShell would use the cmd script instead. I foresee with this addition it will cause many confusion among people, especially ones who are using the built-in terminal of Visual Studio Code on Windows, which is PowerShell.

References

https://github.com/microsoft/TypeScript/issues/35031
https://stackoverflow.com/questions/58796490/tsc-ps1-cannot-be-loaded-because-running-scripts-is-disabled-on-this-system
And the following some newer answers even suggest deleting the ps1 file.
https://stackoverflow.com/questions/57673913/vsc-powershell-after-npm-updating-packages-ps1-cannot-be-loaded-because-runnin

Needs Discussion Question

Most helpful comment

Delete all *.ps1 scripts in the npm bin directory?

All 13 comments

@Cerlancism. type the following commands in powershell

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned

or

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine

after run your .ps1 PowerShell script

@Cerlancism
In https://github.com/npm/read-cmd-shim/pull/6 , I only add extract path from powershell support.
This function is for https://github.com/npm/cli/pull/281

If you want to know why is *.ps added when install package, please see this: https://github.com/npm/cmd-shim/pull/34

PowerShell scripts are also the only ones which provide a built‑in way to pipe stdin through into the Node.js process (https://github.com/npm/cmd-shim/pull/43) when pipeline input has been passed to the script.

Just installed latest NPM on a fresh machine and this is very disturbing behavior while it used to work out of the box.

Solution provided by @RAJU2529 is fine as long as you can do whatever you want on your machine. On domain-joined machine, this setting can be driven by organization settings and cannot be overridden, even if the user is admin on the machine.
Does anyone have another workaround, except downgrading NPM version?

Delete all *.ps1 scripts in the npm bin directory?

@ExE-Boss that's what I ended doing for now, but it really is a workaround...

Agree to the above too. Better than changing your execution policy...I know it works and all and people are likely to be running scripts but...just completely silly

We recently updated our build servers to the latest LTS of node.
Some of our PowerShell-Scripts use code like:

Start-Process "npm-cli-login" [...] -NoNewWindow

If you ask powershell which executable it uses ((Get-Command npm-cli-login).Source) you get the newly created ps1-Files instead of the cmd.

The process exits with %1 is not a valid win32 application because a ps1-script is no valid executable.

This is a breaking change within a version and should be at least reviewed.

Delete all *.ps1 scripts in the npm bin directory?

Do we have a way to force Windows to not create the .ps1 script while using npm link or npm i -g ../<package> ? It is kinda frustrating to have to go on the npm folder and clean this mess all the time.

One quick workaround if your system has Command Prompt is to tell PowerShell to use the cmd version instead: <package-name>.cmd

For example for TypeScript:
instead of
tsc -v which now calls tsc.ps1 in PowerShell
use
tsc.cmd -v

One quick workaround if your system has Command Prompt is to tell PowerShell to use the cmd version instead: <package-name>.cmd

Yes, if you add .cmd powershell uses the correct executable.

But if you have versioned build scripts that should not change after a release, you have only two possibilities:

  • Change it anyway
  • Don't update node -> possible security problem.

The pull request 34 which added this feature references it as a fix for npm issue 20699. Checking that issue, it seems like the core problem is passing the ampersand character as a command argument on the windows command line. That is interpreted as a command delimiter so it errors.

image

However, in windows command line, we can escape the ampersand character with a caret. ^&

image

Longshot, but could this be a feasible alternative solution to what was implmented that introduced these breaking changes? Is there some way we could detect that an argument is destined for the windows command line and regex or inject the caret character into the argument as an escape? Does anyone like @ExE-Boss boss know if there some reason we couldn't have addressed this issue using something similar?

The following document covers the best way to handle windows command line argument parsing. Use it as a guide?
https://docs.microsoft.com/en-us/archive/blogs/twistylittlepassagesallalike/everyone-quotes-command-line-arguments-the-wrong-way

I think pipes are also not working using ps1 scripts related to this.

I am trying around the following highly used tools:
prettyjson
prettier

For example when I run the following on Powershell:
echo '{"a": 1}' | prettyjson

The terminal will just keep waiting for inputs till CTRL+C pressed and it exits with no expected output.

The workaround is to add .cmd to the command or just use cmd instead:
echo '{"a": 1}' | prettyjson.cmd

Outputs

a: 1

My question on stackoverflow: https://stackoverflow.com/questions/62951533/why-pipes-are-not-working-on-powershell-for-various-nodejs-cli-tools

Update

Sorry, I just recalled it was commented here before https://github.com/npm/cli/issues/470#issuecomment-568165144 about stdin piping and the PR is here https://github.com/npm/cmd-shim/pull/43 . But still, using .cmd seems to work for pipes.

Was this page helpful?
0 / 5 - 0 ratings