Azure Pipeline:如何在部署目标VM上运行批处理脚本停止服务?
解决Azure流水线中在目标VM执行脚本停止服务的问题
你完全说对了——BatchScript@1任务是在流水线的代理虚拟机上运行的,而不是你要部署的目标VM,这就是为什么会出现'pm2' is not recognized的错误:代理机上没安装pm2,你的目标VM才是装有pm2的机器。
要在目标VM上执行停止服务的脚本,你需要用专门的Azure任务来远程触发目标VM上的命令,下面是几种可靠的解决方案:
方法1:使用Azure CLI任务调用az vm run-command
这是最直接的方式,利用Azure CLI的vm run-command命令直接在目标VM上执行脚本,无需额外配置太多依赖。
你可以在AzureFileCopy@3任务之前添加一个AzureCLI@2任务,示例配置如下:
- task: AzureCLI@2 inputs: azureSubscription: 'qa-serverside-snapshots' # 和你AzureFileCopy用的订阅一致 scriptType: 'ps' scriptLocation: 'inlineScript' inlineScript: | # 替换<你的VM名称>为目标VM的实际名称 az vm run-command invoke ` --resource-group SERVERSIDE-SNAPSHOTS ` --name <你的VM名称> ` --command-id RunPowerShellScript ` --scripts "C:\Users\$(username)\AppData\Roaming\npm\pm2.cmd stop myservice"
注意点:
- Windows上npm全局安装的pm2通常在用户目录的
AppData\Roaming\npm路径下,用完整路径调用pm2.cmd能避免PATH环境变量的问题; - 如果你的目标VM有多个,需要为每个VM单独执行这个命令,或者用循环批量处理。
方法2:使用PowerShell远程执行
因为你开启了enableCopyPrerequisites: true,Azure已经帮目标VM配置好了基础的WinRM,你可以用PowerShell远程连接到目标VM执行命令:
- task: PowerShell@2 inputs: targetType: 'inline' script: | $securePassword = ConvertTo-SecureString $(password) -AsPlainText -Force $credential = New-Object System.Management.Automation.PSCredential ($(username), $securePassword) Invoke-Command -ComputerName <目标VM的IP或主机名> -Credential $credential -ScriptBlock { & "C:\Users\$using:username\AppData\Roaming\npm\pm2.cmd" stop myservice }
方法3:使用Azure VM Run Command任务
Azure DevOps还有专门的AzureVMRunCommand@0任务,专门用来在目标VM上执行命令,配置更直观:
- task: AzureVMRunCommand@0 inputs: azureSubscription: 'qa-serverside-snapshots' ResourceGroupName: 'SERVERSIDE-SNAPSHOTS' VMName: '<你的VM名称>' CommandId: 'RunPowerShellScript' InlineScript: | C:\Users\$(username)\AppData\Roaming\npm\pm2.cmd stop myservice
关键步骤顺序
不管用哪种方法,一定要把停止服务的任务放在AzureFileCopy@3之前,确保复制文件时目标路径的文件已经被释放,不会被服务占用。如果需要,复制完成后还可以添加一个相同类型的任务来重启服务。
内容的提问来源于stack exchange,提问作者Nicholas Siegmundt
相关产品推荐
相关产品推荐

