Nodejs installation via PowerShell

Nodejs installation via PowerShell

ยท

6 min read

As a developer, we love to automate the boring and manual stuff which could range from installation of applications, backing-up files, automatic system health-checks etc.

In this article, I would be discussing how to install any nodejs version on your system by just executing a PowerShell script.

NVM is used in this setup for easy installation of nodejs and npm versions and it also makes switching between various versions easy.

In this tutorial the Operating System targeted is Windows. The flow chart below describes the execution flow of the script.

The script used to implement this flow chart can be seen below:

function Install-Dependencies() {
    param ( [Parameter(Mandatory)] [string]$nodeVersion)
    if (Get-Command nvm -ErrorAction SilentlyContinue) {
        Write-Host "Downloading node..." -ForegroundColor Yellow
        Install-NodeModules
    }
    else {
        $folder = "$Home\nvm"
        $zipFile = "$Home\nvm.zip"
        $nodePath = "$Home\nodejs"
        $settingsFileLocation = "$folder/settings.txt"
        $settingsFileName = "settings.txt"
        if (Test-Path $nodePath) {
            Remove-Item -Recurse -Force $nodePath
        }
        if (Test-Path $folder) {
            Remove-Item -Recurse -Force $folder
        }
        Invoke-WebRequest -Uri "https://github.com/coreybutler/nvm-windows/releases/download/1.1.7/nvm-noinstall.zip" -OutFile $zipFile
        Expand-Archive -path $zipFile -DestinationPath $folder
        Remove-Item $zipFile
        $path = [System.Environment]::GetEnvironmentVariable("Path", "User")
        [System.Environment]::SetEnvironmentVariable("NVM_HOME", $folder, "User")
        [System.Environment]::SetEnvironmentVariable("NVM_SYMLINK", $nodePath, "User")
        $newPath = $path + ";$folder;$nodePath"
        [System.Environment]::SetEnvironmentVariable("Path", $newpath, 'User')
        $env:Path += $newPath
        $env:NVM_HOME = $folder
        $env:NVM_SYMLINK = $nodePath
        New-Item -Path $folder -Name "$settingsFileName"
        Add-Content -Path $settingsFileLocation  -Value "root: $folder"
        Add-Content -Path $settingsFileLocation -Value "path: $nodePath"
        Write-Host "Downloading node..." -ForegroundColor Yellow
        Install-NodeModules
    }
}
function Install-NodeModules() {
    if ([string]$(nvm install $nodeVersion).Contains("not yet released")) {
        Write-Host "nodejs $nodeVersion version isn't available please try a different version"
    }
    else {
        nvm install $nodeVersion
        nvm use $nodeVersion
        Start-Sleep -s 1
        Write-Host "Installing node modules...." -ForegroundColor Yellow
        npm install express
        #Run Script
    }

}

Install-Dependencies

So let me break down the script ๐Ÿคฉ

param ( [Parameter(Mandatory)][string] $nodeVersion)

The Param function allows you to pass in named arguments(parameters) to your script.

The [Parameter(Mandatory)] attribute demands that your script shouldn't execute without passing in the required parameter.

The [string]$nodeVersion casts your nodeVersion parameter to a string.

if(Get-Command nvm -ErrorAction SilentlyContinue) {
       Write-Host "Downloading node..." -ForegroundColor Yellow
       Install-NodeModules
    }

The Get-Command nvm -ErrorAction SilentlyContinue command is a trick used to check if a command is available.

The -ErrorAction SilentlyContinue parameter-value ensures that when Get-Command nvm throws an error, the if block returns false instead of terminating the script.

The Write-Host "Downloading node..." -ForegroundColor Yellow command logs out the "Downloading node..." TEXT to the terminal using a yellow coloured text.

The Install-NodeModules command is used to execute the Install-NodeModules function.

 $folder = "$Home\nvm"
 $zipFile = "$Home\nvm.zip"
 $nodePath = "$Home\nodejs"
 $settingsFileLocation = "$folder/settings.txt"
 $settingsFileName = "settings.txt"

It is a good practice to define values that would be reused in various areas of your code as variables.

The variables above stores locations to various files and directories.

In PowerShell, the $Home variable returns the path to the root of the current user.

if (Test-Path $nodePath) {
      Remove-Item -Recurse -Force $nodePath
}
if (Test-Path $folder) {
       Remove-Item -Recurse -Force $folder
}

The Test-Path command returns true if a path exists and false if it doesn't.

The Remove-Item -Recurse -Force command deletes a path (folder or file).

Invoke-WebRequest -Uri [Link to download nvm files] -OutFile $zipFile
Expand-Archive -path $zipFile -DestinationPath $folder
Remove-Item $zipFile

The Invoke-WebRequest command downloads the data from the desired link via the -Uri parameter into a file via the -OutFile parameter.

Unlike curl where you have to define the -L parameter to follow a redirect, the Invoke-WebRequest follows a redirect by default ๐Ÿคฉ.

The Expand-Archive command is a utility command that can be used to unzip a zip file into a folder. It uses the -path parameter to define the location of the zip file and the -DestinationPath parameter to define the location of the folder that would contain the uncompressed data after unzipping.

After unzipping the node version manager files into the desired path. I decided to delete the downloaded zipped file using the Remove-Item command.

$path = [System.Environment]::GetEnvironmentVariable("Path", "User")
[System.Environment]::SetEnvironmentVariable("NVM_HOME", $folder, "User")
[System.Environment]::SetEnvironmentVariable("NVM_SYMLINK", $nodePath, "User")
$newPath = $path + ";$folder;$nodePath"
[System.Environment]::SetEnvironmentVariable("Path", $newpath, 'User')

The code block above sets various environmental variables needed for the proper installation of nvm.

I made use of this instruction to know the required variables.

The [System.Environment]::GetEnvironmentVariable("Path", "User") retrieves the path environenmental variable for the current user and sets them to the $path variable.

The [System.Environment]::SetEnvironmentVariable is used to permanently set an environmental variable. It takes a second parameter that defines which scope the variable is to be set and stored in. In the code block above I chose the User scope.

$env:Path += $newPath
$env:NVM_HOME = $folder
$env:NVM_SYMLINK = $nodePath

To make the environmental variable changes available in the current process without creating a new shell, the $env:[variable]=[value] command is used.

 New-Item -Path $folder -Name "$settingsFileName"
 Add-Content -Path $settingsFileLocation  -Value "root: $folder"
 Add-Content -Path $settingsFileLocation -Value "path: $nodePath"

The New-Item command is used here to create a file while the Add-Content command is used to add text to the created file

 if ([string]$(nvm install $nodeVersion).Contains("not yet released")) {
    Write-Host "nodejs $nodeVersion version isn't available please try a different version"
 }

The [string] attribute is used to cast the output of nvm install $nodeVersion into a string. And the Contains method returns true if the out of nvm install $nodeVersion contains "not yet released". This line of code is defined for situations where the inputted node version isn't available.

nvm install $nodeVersion
nvm use $nodeVersion
Start-Sleep -s 1
Write-Host "Installing node modules...." -ForegroundColor Yellow
npm install express

Finally, the code block above is used to install the inputted node version and set the installed version to be the current systems node version.

PS:- I prefer PowerShell to bash ๐Ÿ˜…

Here is a link to the code: mycode

Thanks for reading and please do share it too .....yay!!!