Skip to content

Instantly share code, notes, and snippets.

@euaaron
Last active March 4, 2024 13:56
Show Gist options
  • Save euaaron/8b0a2497244b3711e65ad798bdc5873f to your computer and use it in GitHub Desktop.
Save euaaron/8b0a2497244b3711e65ad798bdc5873f to your computer and use it in GitHub Desktop.
Windows CLI - Powershell script to download and switch between different Nodejs versions.
# --------------------------------------------
# Nodejs Version Manager Powershell (nmp)
# v1.0.2
# Author: Aaron Carneiro <@euaaron>
# Email: nmp@aaroncarneiro.com
# GitHub: https://github.com/euaaron
# This File: https://gist.github.com/euaaron/8b0a2497244b3711e65ad798bdc5873f
# --------------------------------------------
$nmpVersion = "v1.0.2"
$silentInit = $false
# To install just paste the code below to your Powershell $profile file and run:
# nmp -init -dir "C:\path\to\install"
# If you face Execution Policy error, try uncomment the line below or copy the code and run it on Powershell
# Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope CurrentUser
# Learn more at https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy?view=powershell-7.3
# NMP depends on CreateDir and Test-CommandExists functions which are right below.
# These functions are also available for you to use on your Powershell if you want.
# If you don't want them to be exposed, just move them to inside nmp function
function CreateDir {
param(
[string] $Dir = ""
)
if (-Not $Dir -Contains "*:\") {
$tempDir = $Dir;
$Dir = ([System.Environment]::CurrentDirectory)
$Dir += "\"
$Dir += $tempDir;
}
if (-Not (Test-Path $Dir)) {
$dirPath = $Dir.Split("\");
$currentPath = ""
$count = 0;
$dirPath | ForEach {
if (-Not ($dirPath[$count] -Eq "") -Or -Not ($dirPath[$count] -Eq "\")) {
$currentPath += $dirPath[$count]
$currentPath += "\"
$currentPath = $currentPath.Replace("\\", "\");
if (-Not (Test-Path $currentPath) -And -Not ($currentPath -Eq "")) {
mkdir $currentPath
}
}
if (-Not ($dirPath.Length - 1 -Eq $count)) {
$count += 1;
} else {
Write-Host "Directory '$currentPath' has been created suceessfully!"
return;
}
}
} else {
Write-Host "Error! '$dir' already exists!"
}
return;
}
Function Test-CommandExists {
Param ($command, [switch] $silent)
$oldPreference = $ErrorActionPreference
$ErrorActionPreference = 'stop'
$exists = $false;
try {
if(Get-Command $command){
$exists = $true
if (-Not $silent) {
Write-Host "Command $command exists!"
}
}
}
Catch {
$exists = $false
if (-Not $silent) {
Write-Host "Command $command was not found!"
}
}
$ErrorActionPreference=$oldPreference
return $exists;
}
function nmp {
param(
[string] $change = "",
[string] $arch = "win-x64",
[switch] $force,
[switch] $version,
[switch] $list,
[switch] $remote,
[switch] $help,
[switch] $init,
# Directory to install Nodejs versions
[string] $dir = "C:\Softwares\nodejs\",
# Default Nodejs version to use
[string] $default = "18"
)
function nInit {
# Creates this directory if not exists
if (-Not (Test-Path $dir)) {
CreateDir -Dir $dir
}
# Directory of Default Node Version
# If you already have Nodejs installed, set this path with your nodejs dir. It might be "C:\Program Files\nodejs\"
$defaultNodeDir = $dir + $default;
# This will change default installed Nodejs version with the new one in the path (also npm and npx that come pre-installed with nodejs)
$systemPath = $env:Path
$systemPath = $systemPath.Replace('C:\Program Files\nodejs\;', $defaultNodeDir + "\;");
$env:Path = $systemPath;
# If you don't had NodeJs installed previously, remove the three lines above and uncomment the line bellow
# $env:Path += $defaultNodeDir;
}
# This function will switch current terminal to use a different Nodejs version.
# It will first check at $dir, if not found it will try to install directly from nodejs.org.
function nChange {
param (
[string] $version = '',
[string] $arch = "win-x64",
$force = $false
)
if ($version -ne '') {
$versionDir = $dir + $version + "\";
if (-Not (Test-Path $versionDir) -Or $force) {
$remoteNodeVersions = (Invoke-WebRequest -Uri "https://nodejs.org/dist/").Links.Href;
if ($remoteNodeVersions -like "latest-v$version.*") {
$temp = $dir + "temp";
if (Test-Path $temp) {
rm -r -Force $temp
}
if (Test-Path $versionDir) {
rm -r -Force $versionDir
}
mkdir $temp
$downloadUrl = "https://nodejs.org/dist/latest-v$version.x/";
(Invoke-WebRequest -Uri $downloadUrl).Links.Href | ForEach {
if ($_ -like "node-v$version.*" -and $_ -like "*-$arch.zip") {
$downloadUrl = $downloadUrl + $_
}
}
Write-Host "Downloading Nodejs $version from $downloadUrl"
Invoke-WebRequest -Uri $downloadUrl -OutFile "$temp\$version.zip"
Write-Host "Downloaded Nodejs $version to $temp\$version.zip"
Write-Host "Extracting $temp\$version.zip to $versionDir"
Expand-Archive -Path $temp\$version.zip -DestinationPath $versionDir
mv "$versionDir\node-v$version.*\*" $versionDir
rm -r -Force "$versionDir\node-v$version.*"
Write-Host "Removing temp folder."
rm -r -Force $temp
} else {
Throw "Version $version is invalid! Please, run nmp -list -remote to see available versions and run this command again. Ex.: nmp -change 16"
}
}
Write-Host "Setting Nodejs $version the current active version."
$currentVersion = (node -v).Replace('v', '').Split('.')[0]
$replaceVersionDir = $dir + $currentVersion + '\;'
$systemPath = $env:Path
$systemPath = $systemPath.Replace($replaceVersionDir, "$versionDir;");
$env:Path = $systemPath;
node -v
} else {
$env:Path = $defaultNodeDir;
if (Test-CommandExists -command node -silent) {
node -v
} else {
Write-Host "You need to restart your terminal to see the changes."
}
}
}
# This lists all Nodejs versions that are possible to install by running nChange
function nList {
param (
[switch] $remote
)
if ($remote.IsPresent) {
(Invoke-WebRequest -Uri "https://nodejs.org/dist/").Links.Href | ForEach {
if ($_ -like "latest-v*" -and -not ($_ -like "latest-v0*")) {
$version = $_.Replace('latest-', '').Replace('.x/', '');
Write-Host $version
}
}
Write-Host "These are current available Nodejs versions (latest)"
} else {
ls $dir
}
}
function nVersion {
Write-Host "Nodejs Version Manager Powershell (nmp)"
Write-Host $nmpVersion
Write-Host "---------------------------------------"
if (Test-CommandExists node -silent) {
$nodeV = (node -v)
Write-Host "Node $nodeV"
} else {
Write-Host "Node.js is not installed! Run nmp -help to see how to install Node.js using nmp."
}
}
# Displays all available functions
function nHelp {
Write-Host 'Node Version Manager Powershell - Help'
Write-Host ''
Write-Host '-version | Display current nmp and node versions.'
Write-Host '-list | List all Nodejs versions currently installed.'
Write-Host ' -remote | List all Nodejs versions available to install.'
Write-Host '-change $number | Changes Nodejs version ($number). If not installed, it will download it.'
Write-Host ' Ex. nmp -change 18 will install latest v18, like 18.13.0.' -ForegroundColor Yellow
Write-Host ' -force | Will attempt to override a current version.'
Write-Host ' Usefull to update versions from 18.0.4 to 18.4.1, for example.' -ForegroundColor Yellow
Write-Host ' -arch | Default to "win-x64", can also be "win-x86".'
Write-Host '-help | Display this help page.'
}
if ($help.IsPresent) {
nHelp
} else {
if ($list.IsPresent) {
if (-Not $remote.IsPresent) {
nList
} else {
nList -remote
}
}
if (-Not ($change -Eq "")) {
nChange -version $change -arch $arch -force $force.IsPresent
}
if ($version.IsPresent) {
nVersion
}
if ($init.IsPresent -Or $PSBoundParameters.ContainsKey('dir')) {
try {
nInit
if (-Not $silentInit) {
nVersion
}
}
catch {
Write-host "Could not load nmp, you may need to ajust some configs in your Powershell Profile."
}
}
}
}
nmp -init
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment