通过Jenkins执行PowerShell脚本安装NodeJS组件时PM2验证失败
问题
在Windows系统的EC2实例上编写了PowerShell脚本,用于安装NodeJS、NPM、PM2和Yarn。直接在EC2实例上运行该脚本时一切正常,但通过Jenkins流水线执行时,NodeJS安装成功,PM2和Yarn虽显示安装完成,但验证PM2版本时提示该命令未被识别。
脚本内容
$target="c:/omnilink/assetwhere/platform/node.msi" function SetPathVariables { [CmdletBinding()] param ( [string]$PathName ) $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") [Environment]::SetEnvironmentVariable('Path', $env:Path + ';'+$PathName, 'Machine') #Removing duplicates [Environment]::SetEnvironmentVariable('Path',(([Environment]::GetEnvironmentVariable('Path','Machine') -split ';'|Sort-Object -Unique) -join ';'),'Machine') $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") } echo "Downloading nodeJS" Read-S3Object -BucketName assetwhere-build-components -File $target -Key 'Components/Nodejs/node-v18.12.1-x64.msi' echo "Installing NodeJS" Start-Process msiexec.exe -Wait -ArgumentList '/I C:\omnilink\assetwhere\platform\node.msi /quiet' echo "Setting Path" SetPathVariables -PathName 'C:\Program Files\nodejs\' echo "Verifying NodeJS Installation" node --version npm --version echo "Successfully Installed NodeJS" echo "Installing yarn" npm install --global yarn echo "Installing pm2" npm install --global pm2 SetPathVariables 'C:\Users\Administrator\AppData\Roaming\npm' echo "Verifying global packages installations" echo "Yarn Version: " yarn --version echo "Pm2 Version: " pm2 --version
Jenkins日志
Downloading nodeJS Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 1/7/2023 10:49 AM 30683136 node.msi Installing NodeJS Setting Path Verifying NodeJS Installation v18.12.1 8.19.2 Successfully Installed NodeJS Installing yarn added 1 package, and audited 2 packages in 920ms found 0 vulnerabilities Installing pm2 added 184 packages, and audited 185 packages in 23s 12 packages are looking for funding run `npm fund` for details found 0 vulnerabilities Verifying global packages installations Pm2 Version: pm2 : The term 'pm2' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. At C:\omnilink\configure\InstallAssetWhereAPIRequirementsScript.ps1:36 char:1 + pm2 --version + ~~~ + CategoryInfo : ObjectNotFound: (pm2:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException
原因分析
- 当前会话环境变量未即时刷新:Jenkins的PowerShell进程在启动时就加载了系统环境变量,即使脚本更新了Machine级别的Path,当前运行脚本的进程不会自动重新读取更新后的Path,导致找不到刚安装的全局命令。
- 用户上下文不匹配:Jenkins服务通常不是以
Administrator用户身份运行(比如默认用Local System账户),此时npm全局包的安装路径不是C:\Users\Administrator\AppData\Roaming\npm,而是Jenkins运行用户对应的AppData目录,硬编码路径会导致路径错误。
解决方案
1. 修复环境变量刷新逻辑
修改SetPathVariables函数,确保更新Machine级Path的同时,直接同步更新当前会话的$env:Path:
function SetPathVariables { [CmdletBinding()] param ( [string]$PathName ) # 获取系统级Path并处理去重 $machinePath = [System.Environment]::GetEnvironmentVariable("Path","Machine") $updatedPath = (($machinePath -split ';' | Where-Object { $_ -and $_ -ne $PathName }) + $PathName | Sort-Object -Unique) -join ';' # 更新系统级Path [Environment]::SetEnvironmentVariable('Path', $updatedPath, 'Machine') # 立即更新当前会话的Path $env:Path = $updatedPath }
2. 动态获取npm全局路径
不要硬编码全局包路径,通过npm config get prefix获取实际路径,再添加到环境变量:
# 安装完yarn和pm2后 $npmGlobalPath = npm config get prefix SetPathVariables -PathName $npmGlobalPath
3. 直接使用完整路径验证
如果不想修改环境变量,可直接调用全局命令的完整路径来验证:
$npmPrefix = npm config get prefix & "$npmPrefix\pm2" --version & "$npmPrefix\yarn" --version
内容的提问来源于stack exchange,提问作者Srinivas
相关产品推荐
相关产品推荐

