升级至Puppet 5.3.3后执行PowerShell脚本返回错误码1求助
我之前也碰到过类似的情况,升级到Puppet 5.x系列后,PowerShell脚本通过Exec执行时经常出现退出码不匹配的问题——直接跑脚本完全正常,但Puppet就是返回错误码1。这本质是Puppet 5.x对powershell provider的退出码处理逻辑,相比4.x有了更严格的变化。下面是具体的排查和解决步骤:
问题根源
你直接在PowerShell里运行脚本时,会话的退出码默认是最后一条命令的执行结果,但Puppet 5.x的powershell provider会严格校验整个PowerShell会话的退出码是否为0(除非你主动指定returns参数覆盖)。你的脚本虽然捕获了notepad的退出码,但没有显式让PowerShell会话返回这个值,导致Puppet接收到的是PowerShell隐式生成的默认退出码(大概率是1,来自某个你没注意到的操作结果)。另外错误信息里的'C:/build/test.ps1 notepad'也暗示,Puppet对命令的解析方式可能需要调整。
解决方案
1. 在PowerShell脚本末尾显式返回退出码
修改你的脚本,在最后加上exit $EXIT_CODE,强制让PowerShell会话返回你捕获的进程退出码:
Write-Host "Starting notepad ..." [System.Diagnostics.Process] $proc = Start-Process -FilePath notepad -PassThru -Wait -ErrorAction stop $EXIT_CODE=$proc.exitcode Write-Host "notepad exit code is (${EXIT_CODE})" exit $EXIT_CODE # 显式指定PowerShell会话的退出码
2. 修正Puppet Exec资源的命令调用方式
在Puppet清单中,用PowerShell的调用操作符&来执行脚本,确保Puppet能正确解析命令:
Exec { provider => powershell, } exec { 'test': command => '& C:/build/test.ps1', timeout => '0', logoutput => true, # 如果notepad有合法的非0退出码场景,可以添加returns参数覆盖默认校验 # returns => [0, 1, 2], }
3. 可选:统一错误处理策略
如果脚本里还有其他可能抛出错误的操作,可以在脚本开头添加$ErrorActionPreference = 'Stop',确保任何错误都会终止脚本并返回对应退出码,避免隐式错误导致Puppet误判。
验证步骤
- 先直接修改脚本并在PowerShell中运行,用
$LASTEXITCODE查看退出码是否符合预期; - 更新Puppet清单后,执行
puppet agent -t测试,应该不会再出现返回码1的错误提示。
内容的提问来源于stack exchange,提问作者Steve Cretchley

