声明式Jenkins结合WithCredentials与PowerShell部署报错求助
解决Jenkins流水线凭据不匹配及远程部署问题
你碰到的这个错误:
org.jenkinsci.plugins.credentialsbinding.impl.CredentialNotFoundException: Credentials 'Test' is of type 'Username with password' where 'org.jenkinsci.plugins.plaincredentials.StringCredentials' was expected.
本质是凭据类型不匹配,再加上原代码里的远程部署逻辑还有几个隐藏问题,我来帮你彻底解决:
错误根源分析
你用了string类型的凭据绑定方法,但你的Test凭据是「用户名密码」类型——Jenkins的string绑定仅适用于纯字符串凭据(比如API Token),而用户名密码凭据需要用专门的usernamePassword绑定方式,类型不匹配就会抛出这个错误。
除此之外,原代码还有两个关键问题:
- 每个
powershell步骤都是独立进程,你在前面步骤创建的PSSession变量到后面步骤就失效了,导致Copy-Item找不到目标会话; - IIS相关命令是在Jenkins本地执行的,根本没跑到目标部署服务器上。
修正后的完整流水线代码
我把代码重构了一遍,解决了所有问题:
stage('Deployment') { steps { // 正确绑定用户名密码类型凭据 withCredentials([usernamePassword( credentialsId: 'Test', usernameVariable: 'DEPLOY_USER', passwordVariable: 'DEPLOY_PASS' )]) { powershell ''' # 构建远程登录的安全凭据对象 $securePass = ConvertTo-SecureString -AsPlainText "$env:DEPLOY_PASS" -Force $remoteCreds = New-Object System.Management.Automation.PSCredential("$env:DEPLOY_USER", $securePass) # 建立与目标服务器的远程会话 $remoteSession = New-PSSession -ComputerName 192.123.123.123 -Credential $remoteCreds # 将Jenkins上的制品复制到远程服务器 Copy-Item "$env:ARTIFACT_PATH" -Destination "$env:DESTINATION_PATH" -ToSession $remoteSession -Recurse -Force # 在远程服务器上执行IIS部署操作 Invoke-Command -Session $remoteSession -ScriptBlock { # 重置IIS确保无锁定资源 Start-Process "iisreset.exe" -NoNewWindow -Wait # 清理旧的网站、应用池和绑定(不存在则忽略错误) Remove-Website -Name WebCareRecord -ErrorAction SilentlyContinue Remove-WebAppPool WebCareRecord -ErrorAction SilentlyContinue Get-WebBinding -Port 85 -Name WebCareRecord | Remove-WebBinding -ErrorAction SilentlyContinue # 再次重置IIS释放资源 Start-Process "iisreset.exe" -NoNewWindow -Wait # 创建新的应用池并配置 New-WebAppPool -Name WebCareRecord Set-ItemProperty "IIS:\\AppPools\\WebCareRecord" managedPipelineMode 0 Set-ItemProperty "IIS:\\AppPools\\WebCareRecord" managedRuntimeVersion "" # 创建新网站并关联应用池 New-WebSite -Name WebCareRecord -Port 85 -PhysicalPath "$using:PHYSICAL_PATH" -ApplicationPool WebCareRecord # 最后重置IIS使配置生效 Start-Process "iisreset.exe" -NoNewWindow -Wait } # 关闭远程会话释放资源 Remove-PSSession $remoteSession ''' } } }
关键修改细节
- 凭据绑定修正:把
string换成usernamePassword,精准匹配你的凭据类型,同时用$env:变量名的方式引用Jenkins注入的凭据变量,这是PowerShell读取环境变量的标准做法。 - 整合PowerShell步骤:将所有远程操作放到同一个
powershell块里,避免跨步骤的变量丢失——毕竟每个powershell都是独立进程,之前的会话变量到下一个步骤就找不到了。 - 远程执行IIS命令:用
Invoke-Command把IIS相关命令放到远程会话中执行,原代码的IIS命令其实是在Jenkins本地跑的,完全达不到部署到目标服务器的目的。 - 容错处理优化:清理旧资源时加上
-ErrorAction SilentlyContinue,就算旧网站/应用池已经被删除,流水线也不会直接报错终止。 - 本地变量传递:在远程脚本块里引用Jenkins的
PHYSICAL_PATH变量时,用$using:关键字把本地变量传递到远程会话中,否则远程服务器无法识别这个变量。
内容的提问来源于stack exchange,提问作者Spidy
相关产品推荐
相关产品推荐

