$ErrorActionPreference = "Stop"
$ProgressPreference = 'SilentlyContinue'
$NodeJsMinMajor = 20
$NodeJsInstallVersion = "22"
$NodeJsInstallFullVersion = "22.11.0"
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$UtilsScript = Join-Path $ScriptDir "utils.ps1"
. $UtilsScript
function Test-NodeInstalled {
$null = Get-Command node -ErrorAction SilentlyContinue
if ($?) {
$VersionStr = (node -v) -replace "v", ""
$InstalledMajor = [int]($VersionStr -split "\." | Select-Object -First 1)
if ($InstalledMajor -ge $NodeJsMinMajor) {
return $true
} else {
Write-Log "WARN" "Node.js detected but version $(node -v), requires Node.js $NodeJsMinMajor.0 or above"
return $false
}
}
return $false
}
function Install-NodeJs {
Write-Log "INFO" "Starting automatic installation of Node.js v$NodeJsInstallVersion (meets $NodeJsMinMajor.0+ requirement)"
$TempDir = Join-Path $env:TEMP "NodeJsInstall"
if (-not (Test-Path $TempDir)) {
New-Item -ItemType Directory -Path $TempDir | Out-Null
}
$InstallerPath = Join-Path $TempDir "node-v$NodeJsInstallFullVersion-x64.msi"
$DownloadUrls = @(
"https://openjiuwen-ci.obs.cn-north-4.myhuaweicloud.com/agentstudio/depends/node-v$NodeJsInstallFullVersion-x64.msi",
"https://nodejs.org/dist/v$NodeJsInstallFullVersion/node-v$NodeJsInstallFullVersion-x64.msi"
)
$DownloadSuccess = $false
foreach ($InstallerUrl in $DownloadUrls) {
Write-Log "INFO" "Attempting to download Node.js installer from: $InstallerUrl"
try {
Invoke-WebRequest -Uri $InstallerUrl -OutFile $InstallerPath -UseBasicParsing
Write-Log "SUCCESS" "Node.js installer downloaded successfully from: $InstallerUrl"
$DownloadSuccess = $true
break
} catch {
Write-Log "WARN" "Failed to download from $InstallerUrl : $($_.Exception.Message)"
if ($InstallerUrl -eq $DownloadUrls[-1]) {
Write-Log "ERROR" "Failed to download Node.js installer from all sources"
exit 1
}
Write-Log "INFO" "Trying next download source..."
}
}
if (-not $DownloadSuccess) {
Write-Log "ERROR" "Failed to download Node.js installer from all available sources"
exit 1
}
Write-Log "INFO" "Installing Node.js silently..."
try {
Start-Process -FilePath "msiexec.exe" -ArgumentList "/i $InstallerPath /quiet /qn /norestart" -Wait
Write-Log "SUCCESS" "Node.js installed successfully"
} catch {
Write-Log "ERROR" "Failed to install Node.js: $($_.Exception.Message)"
exit 1
}
Remove-Item -Path $TempDir -Recurse -Force -ErrorAction SilentlyContinue
Start-Sleep -Seconds 2
$NodeJsPath = "C:\Program Files\nodejs"
if (Test-Path $NodeJsPath) {
Write-Log "INFO" "Found Node.js installation at: $NodeJsPath"
$MachinePath = [System.Environment]::GetEnvironmentVariable("PATH", [System.EnvironmentVariableTarget]::Machine)
$UserPath = [System.Environment]::GetEnvironmentVariable("PATH", [System.EnvironmentVariableTarget]::User)
$MachinePathParts = $MachinePath -split ";" | Where-Object { $_ -ne $NodeJsPath -and $_ -ne "" }
$UserPathParts = $UserPath -split ";" | Where-Object { $_ -ne $NodeJsPath -and $_ -ne "" }
$NewMachinePath = "$NodeJsPath;" + ($MachinePathParts -join ";")
[System.Environment]::SetEnvironmentVariable("PATH", $NewMachinePath, [System.EnvironmentVariableTarget]::Machine)
Write-Log "SUCCESS" "Added Node.js path to system PATH (priority)"
$env:PATH = "$NodeJsPath;" + $NewMachinePath + ";" + ($UserPathParts -join ";")
Write-Log "INFO" "Updated current session PATH"
} else {
Write-Log "WARN" "Node.js installation path not found at expected location: $NodeJsPath"
$env:PATH = [System.Environment]::GetEnvironmentVariable("PATH", [System.EnvironmentVariableTarget]::Machine) + ";" + [System.Environment]::GetEnvironmentVariable("PATH", [System.EnvironmentVariableTarget]::User)
}
}
function Verify-NodeJs {
$NodeJsPath = "C:\Program Files\nodejs"
if (Test-Path $NodeJsPath) {
$env:PATH = "$NodeJsPath;" + $env:PATH
}
Start-Sleep -Seconds 1
$NodeExe = Get-Command node -ErrorAction SilentlyContinue
if (-not $NodeExe) {
$NodeExePath = Join-Path $NodeJsPath "node.exe"
if (Test-Path $NodeExePath) {
$env:PATH = "$NodeJsPath;" + $env:PATH
$NodeExe = Get-Command node -ErrorAction SilentlyContinue
}
}
if ($NodeExe) {
$NodeExePath = $NodeExe.Source
Write-Log "INFO" "Using Node.js from: $NodeExePath"
}
if (Test-NodeInstalled) {
$NodeVersion = node -v
$NpmVersion = npm -v
Write-Log "SUCCESS" "Node.js installed successfully! Version: $NodeVersion"
Write-Log "SUCCESS" "NPM installed successfully! Version: $NpmVersion"
} else {
Write-Log "ERROR" "Node.js installation failed, please check manually"
exit 1
}
}
function Apply-Config-ForNpm {
$ProxyConfigPath = Join-Path $PSScriptRoot "user_config.ps1"
if (-not (Test-Path $ProxyConfigPath)) {
return
}
try {
$ProxyConfigContent = Get-Content -Path $ProxyConfigPath -Raw -Encoding UTF8
} catch {
Write-Log "WARN" "Failed to read proxy config file: $ProxyConfigPath, Error: $($_.Exception.Message)"
return
}
$HTTP_PROXY = ""
$HTTPS_PROXY = ""
$SSL_VERIFY = ""
$NPM_REGISTRY = ""
$ENABLE_NPM_PROXY_CONFIG = "true"
if ($ProxyConfigContent -match '(?m)^\s*\$HTTP_PROXY\s*=\s*["''](.*?)["'']\s*$') { $HTTP_PROXY = $Matches[1] }
if ($ProxyConfigContent -match '(?m)^\s*\$HTTPS_PROXY\s*=\s*["''](.*?)["'']\s*$') { $HTTPS_PROXY = $Matches[1] }
if ($ProxyConfigContent -match '(?m)^\s*\$SSL_VERIFY\s*=\s*["''](.*?)["'']\s*$') { $SSL_VERIFY = $Matches[1] }
if ($ProxyConfigContent -match '(?m)^\s*\$NPM_REGISTRY\s*=\s*["''](.*?)["'']\s*$') { $NPM_REGISTRY = $Matches[1] }
if ($ProxyConfigContent -match '(?m)^\s*\$ENABLE_NPM_PROXY_CONFIG\s*=\s*["''](.*?)["'']\s*$') { $ENABLE_NPM_PROXY_CONFIG = $Matches[1] }
$EnableNpmProxy = $true
if (-not [string]::IsNullOrWhiteSpace($ENABLE_NPM_PROXY_CONFIG) -and "$ENABLE_NPM_PROXY_CONFIG".Trim() -match '^(?i:false|0|no)$') {
$EnableNpmProxy = $false
}
if ($EnableNpmProxy) {
if (-not [string]::IsNullOrWhiteSpace($HTTP_PROXY)) {
Write-Log "INFO" "Configuring npm proxy: $HTTP_PROXY"
try {
& npm config set proxy "$HTTP_PROXY" | Out-Null
Write-Log "SUCCESS" "npm proxy configured successfully"
} catch {
Write-Log "WARN" "Failed to configure npm proxy: $($_.Exception.Message)"
}
}
if (-not [string]::IsNullOrWhiteSpace($HTTPS_PROXY)) {
Write-Log "INFO" "Configuring npm https-proxy: $HTTPS_PROXY"
try {
& npm config set https-proxy "$HTTPS_PROXY" | Out-Null
Write-Log "SUCCESS" "npm https-proxy configured successfully"
} catch {
Write-Log "WARN" "Failed to configure npm https-proxy: $($_.Exception.Message)"
}
}
if (-not [string]::IsNullOrWhiteSpace($SSL_VERIFY)) {
$strictSsl = if ($SSL_VERIFY -match '^(?i:false|0|no)$') { "false" } else { "true" }
Write-Log "INFO" "Configuring npm strict-ssl: $strictSsl"
try {
& npm config set strict-ssl "$strictSsl" | Out-Null
Write-Log "SUCCESS" "npm strict-ssl configured successfully"
} catch {
Write-Log "WARN" "Failed to configure npm strict-ssl: $($_.Exception.Message)"
}
}
} else {
Write-Log "INFO" "Skip configuring npm proxy/strict-ssl (ENABLE_NPM_PROXY_CONFIG=$ENABLE_NPM_PROXY_CONFIG)"
}
if (-not [string]::IsNullOrWhiteSpace($NPM_REGISTRY)) {
Write-Log "INFO" "Configuring npm registry: $NPM_REGISTRY"
try {
& npm config set registry "$NPM_REGISTRY" | Out-Null
Write-Log "SUCCESS" "npm registry configured successfully"
} catch {
Write-Log "WARN" "Failed to configure npm registry: $($_.Exception.Message)"
}
}
}
Write-Log "INFO" "=== Starting Node.js ($NodeJsMinMajor.0+) Installation Check ==="
if (Test-NodeInstalled) {
$NodeVersion = node -v
Write-Log "SUCCESS" "Node.js already installed and meets requirement, current version: $NodeVersion"
Verify-NodeJs
} else {
Write-Log "WARN" "Node.js not installed or version below $NodeJsMinMajor.0"
Install-NodeJs
Verify-NodeJs
}
Apply-Config-ForNpm
Write-Log "SUCCESS" "=== Operation Completed ==="
exit 0