I installed nvm yesterday on a machine where I have no admin rights. I decided for separate paths for nvm and npm than the standard Windows paths so I can overcome the need for admin rights.
nvm was able to download versions, but the symlink process did not work, although I could manually create the link with mklink without any trouble.
I decided to check the code, and changed the elevate.cmd file to this:
@setlocal
@echo off
set CMD=%*
set APP=%1
start %CMD%
This version of the file is now working without admin rights and doing it´s job. It would be great to be able to configure this on the settings.txt with some flag, so people who install in differnt paths can work without admin rights.
It is possible your environment does grant the appropriate rights, but by default, user accounts must be part of the Adminstrator group in order to use mklink
. See https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/create-symbolic-links.
Is there any reason to use mklink in place of local user account environment variables? If mklink fails the files could just be copied. Switching, and the directory is not a link, asking to copy changes back.
It's not as simple as just copying node.exe
. The install root contains (by default) the global node_modules
directory and a number of other scripts. So, either _all_ of that needs to be copied/cleaned up, or the npm client config needs to be updated to identify the location of the global node_modules
directory.
Copying takes an enormous amount of time and creates tremendous file system churn when you have mapped/network drives or roaming profiles. Bottom line: there's no guarantee the files will actually be stored on a local hard drive. They could be on a NAS/SAN/etc. Not to mention, it's not uncommon to see gigabytes worth of node modules in each installed version, so even copying on a local hard drive could take quite awhile.
Given how many different versions of npm exist (not to mention it's a commercially-backed tool), manipulating the npm environment to understand where the global node_modules
directory exists is outside the scope of this project. Plus, there's also yarn to consider.
Local environment variables are used. The PATH contains the symlink path. It's not a good idea to be modifying the PATH any more than absolutely necessary (which still requires admin rights). If there is a glitch or error during the process, the entire PATH can be nuked (I tried this in the early days of NVM4W). However; it is possible to change the destination of the symlink, making it unnecessary to modify the PATH environment variable. That's why mklink is used.
So network drives are not supported and Fat32 flash drives can't be supported (does not support mklink). A prompt asking if you really wish to copy files would solve the "file churn" issue. User can enter admin mode. Or they can choose to file churn. Or cancel.
If you copy files, path shouldn't need set that path more than once. And powershell might be able to change the current users (not system) environment path without admin rights. And, if that path gets nuked, the system path will still be safe. Seems a lot less dangerous.
That will take some experimenting. I will give it a shot at work on break or lunch. I've switched to Linux at home.
Doing some more research: "Any Windows 10 user with Developer Mode enabled will be able to create symlinks using either the mklink". That could also be a possible answer. Convince the folks at work that I am a developer and need developer mode enabled.
The question is, will admin mode be needed if developer mode is enabled?
I can't answer authoritatively whether developer mode will negate the need for admin privileges. My guess is yes. However; any operations touching C:\Program Files
require admin privileges (unless developer mode also waives that restriction).
Network drives are supported with mklink when used as a junction. There has been alot of back/forth on the ROI of using junctions, so it has never been implemented.
Remember, Powershell isn't guaranteed to be available in all environments.
I'm not explicitly opposed to the file copying approach, as long as it is a) behind a flag/CLI prompt and b) does not require a visual interface. That last part is important, because there are a number of headless CI services using this.
Why I tend to install development tools c:\programs\ (no admin rights and no spaces in path). c:\programs\nvm and configure node to install to c:\programs\nodejs.
powershell.exe -command '[Environment]::SetEnvironmentVariable("PATH",[Environment]::GetEnvironmentVariable("PATH","User")+"c:\programs\nvm","User")' || XSET PATH "%PATH%;c:\programs\nvm"
Seems to work ok? xset seemed to work too (had to wait a few minutes before they showed up with xset)? I have UAC turned off on the windows pc I am using now. Tomorrow, at work, I'll get to check this out.
tl;dr https://github.com/PowerShell supports Linux (not that I would ever use it there). So I can't think of a environment that powershell can't support that nvm also can't support. node and powershell both run scripts. There is no baked-in, required-signing certificates for node to validate the script is legit and hasn't been tampered with. Powershell has this. npm audit is reactive. imho, node isn't server ready if you need full security. However, most people don't. Proxies are good enough.
It is possible your environment does grant the appropriate rights, but by default, user accounts must be part of the Adminstrator group in order to use
mklink
. See https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/create-symbolic-links.
Creating symlinks doesn't require admin access anymore start from Windows 10 Build 14972, what's more you can use Junction
instead of symlinks
to link, so it is able to work without admin rights when making symlinks in user space like C:\Users\<user>
. Touching C:\Program Files
still require admin rights though.
My question is why not making nvm-windows away from admin rights by default, and if one user is trying to do something with C:\Program Files
or other paths which requires admin rights, then do the permission elevation, instead of requesting admin rights everywhere.
To @mschmiedel If you want to use nvm-windows without admin rights, I have a fork(release) for you, but it can't deal with system-wide Node.js (I didn't test it, it might work under an elevated prompt).
related to #79 #383
@h404bi why not keep admin elevation (I don't think elevate.vbs / .bat shouldn't be blanked). But only execute admin elevation when junction fails and retry is done? The only reason it should fail is due to permissions failing. Such as node or nvm being installed to c:\program files. Otherwise, the pull request looks promising (just looking at the diff).
https://github.com/tamusjroyce/nvm-windows - my attempt at it. But I have never touched golang. I'm pretty sure this will crash and burn. bin/install.cmd as well (though I don't understand how it can unzip the archive it is within?). Not sure why my git corrupted the binaries. But fair warning (best if binaries are separated from source control).
On install, recursively call the install script with elevate.cmd if write permissions to NVM_PATH fails.
echo "Check if nvm path requires admin writes to create file" > %NVM_PATH%\checkpermissions.txt || elevate.cmd install.cmd %NVM_PATH%
https://github.com/tamusjroyce/nvm-windows/commit/7cde75d0ef375cc68c763404b4b3f20b99bbee52
@h404bi My only hesitation with moving away from admin rights by default is the number of users who can take advantage of this are still in the minority, for now. However; times change, and I certainly wouldn't mind getting away from requiring admin privileges. As long as the user experience isn't degraded, it's something I could see being a nice step forward.
That said, there still needs to be a flag for using junctions. This has been on my to-do list for a very long time now. It should be a configuration option... which leads to the bigger challenge. I've been wanting to get rid of the settings.txt
file pretty much ever since the initial release. I've been experimenting with a SQLite approach, which works well in other apps I've been building, but it's not ready for NVM4W yet.
I'll take a look at the forks as soon as I can. I'm not sure when I'll have time though. In the meantime, the best way to get something merged is to make sure it works at least back through Win 8.1.
There are a couple of ways to make mklink work without being admin (up to explicitely granting SeCreateSymbolicLinkPrivilege).
Why not simply try running it and only if it fails retry with elevation?
It's so annoying to enter local admin user credentials twice for each change of node...
My only hesitation with moving away from admin rights by default is the number of users who can take advantage of this are still in the minority, for now.
I am installing nvm
using scoop package manager. Scoop by default install packages to ~/.scoop
. Currently, installing nvm using scoop prompts for admin rights. It would be nice to have this fixed.
@JoyceBabu you can try my fork: https://github.com/h404bi/dorado/blob/master/bucket/nvm-windows.json
I currently have a PowerShell script (It has grown a lot) I made for use by myself and other developers at work (about 200 or so people). I call it âPNM: PowerShell NodeJS Managerâ. This was created as a result of an industry shift in which developers environments are more secured and as a result developers have no admin access (If they do, its usually a different account). I also firmly believe that programs should not be run in with elevated privileges unless absolutely required (regardless if the user has admin rights or not). When I noticed that nvm does not require elevated privileges on other platforms (Linux, OS X, ect) I set out to create a solution that would work the same on Windows.
While it is true that Windows 10 no longer requires admin rights to create/modify symlinks, it DOES require the system to be in âdeveloper modeâ (which requires admin rights to enable). Any environment in which a developer doesnât have admin rights probably not have their workstation in âdeveloper modeâ.
As such, this powershell script takes advantage of user env vars.
The script does the following:
I would be more than happy to help roll these changes into your version of nvm, if you are interested.
@h404bi @coreybutler I am not sure why "symlink no longer requires admin rights" keeps being repeated. It requires you to be in "Developer Mode", which requires admin rights to enable.
Users can be granted access to create symlinks with a permission but it still does not allow the creation of symlinks in restricted directory's (such as program files) without admin access.
@h404bi @coreybutler I am not sure why "symlink no longer requires admin rights" keeps being repeated. It requires you to be in "Developer Mode", which requires admin rights to enable.
Users can be granted access to create symlinks with a permission but it still does not allow the creation of symlinks in restricted directory's (such as program files) without admin access.
NTFS junctions does NOT require admin rights/Developer Mode. You can fallback to use junction while detecting it's not in dev mode on Windows 10.
I was aware of NTFS Junctions but I did not see them mentioned or linked in this thread. Though, I skimmed it rather quickly. Its an interesting concept but experimentation resulted in NTFS Junctions not being cross platform compatible and not working well with network shares. Both of which where required use cases for my environment.
The main reason I prefer to add %PNMNJS% to the user path and update that env var is because its REALLY easy to implement (and account for) across environments (My script supports OSX and Linux through PowerShell Core) and since environment variables can be nested into others, I never have to update PATH directly.
Closing this since the original title issue won't be resolved. I'm not preventing comments though.
@ChrisKader You should just publish your script as a separate tool.
Most helpful comment
@ChrisKader You should just publish your script as a separate tool.