我遇到了一个非常奇怪的情况,即从 Windows Server 2012 R2 手动运行相同的命令时可以工作,但从同一服务器上运行的 Jenkins 从属进程无法工作。
首先,手动运行的输出,管理 PowerShell 窗口:
PS C:\Users\Administrator> whoami
win-cm8utd1qfnc\administrator
PS C:\Users\Administrator> Invoke-Command -computername web.sandbox.MUNGED.com -scriptblock {iisreset /restart}
Attempting stop...
Internet services successfully stopped
Attempting start...
Internet services successfully restarted
伟大的。现在,Jenkins 管道代码的相关片段:
pipeline {
stages {
stage('Deploy web') {
agent { label 'windows-server-2012' }
environment {
SERVER = 'web.sandbox.MUNGED.com'
}
steps {
powershell """
whoami
Invoke-Command -computername ${SERVER} -scriptblock {iisreset /restart}
"""
}
}
}
}
从 Jenkins 运行时的输出:
07:37:29 win-cm8utd1qfnc\administrator
07:37:29 [web.sandbox.MUNGED.com] Connecting to remote server web.sandbox.MUNGED.com failed with the following error message : Access is denied. For more information, see the
07:37:29 about_Remote_Troubleshooting Help topic.
07:37:29 + CategoryInfo : OpenError: (web.sandbox.MUNGED.com:String) [], PSRemotingTransportException
07:37:29 + FullyQualifiedErrorId : AccessDenied,PSSessionStateBroken
Windows 服务器(Jenkins 从属服务器和 Web 服务器)不属于域,但具有相同的管理员密码,这似乎使身份验证工作正常。
就其价值而言,这是 Jenkins 从属设备的 winrm 配置:
PS C:\Users\Administrator> winrm get winrm/config
Config
MaxEnvelopeSizekb = 500
MaxTimeoutms = 1800000
MaxBatchItems = 32000
MaxProviderRequests = 4294967295
Client
NetworkDelayms = 5000
URLPrefix = wsman
AllowUnencrypted = false
Auth
Basic = true
Digest = true
Kerberos = true
Negotiate = true
Certificate = true
CredSSP = false
DefaultPorts
HTTP = 5985
HTTPS = 5986
TrustedHosts = *
Service
RootSDDL = O:NSG:BAD:P(A;;GA;;;BA)(A;;GR;;;IU)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)
MaxConcurrentOperations = 4294967295
MaxConcurrentOperationsPerUser = 1500
EnumerationTimeoutms = 240000
MaxConnections = 300
MaxPacketRetrievalTimeSeconds = 120
AllowUnencrypted = true
Auth
Basic = true
Kerberos = true
Negotiate = true
Certificate = false
CredSSP = false
CbtHardeningLevel = Relaxed
DefaultPorts
HTTP = 5985
HTTPS = 5986
IPv4Filter = *
IPv6Filter = *
EnableCompatibilityHttpListener = false
EnableCompatibilityHttpsListener = false
CertificateThumbprint
AllowRemoteAccess = true
Winrs
AllowRemoteShellAccess = true
IdleTimeout = 7200000
MaxConcurrentUsers = 10
MaxShellRunTime = 2147483647
MaxProcessesPerShell = 4096
MaxMemoryPerShellMB = 8192
MaxShellsPerUser = 30
并从网络服务器:
PS C:\Users\Administrator> winrm get winrm/config
Config
MaxEnvelopeSizekb = 500
MaxTimeoutms = 1800000
MaxBatchItems = 32000
MaxProviderRequests = 4294967295
Client
NetworkDelayms = 5000
URLPrefix = wsman
AllowUnencrypted = false
Auth
Basic = true
Digest = true
Kerberos = true
Negotiate = true
Certificate = true
CredSSP = false
DefaultPorts
HTTP = 5985
HTTPS = 5986
TrustedHosts = *
Service
RootSDDL = O:NSG:BAD:P(A;;GA;;;BA)(A;;GR;;;IU)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)
MaxConcurrentOperations = 4294967295
MaxConcurrentOperationsPerUser = 1500
EnumerationTimeoutms = 240000
MaxConnections = 300
MaxPacketRetrievalTimeSeconds = 120
AllowUnencrypted = true
Auth
Basic = true
Kerberos = true
Negotiate = true
Certificate = false
CredSSP = false
CbtHardeningLevel = Relaxed
DefaultPorts
HTTP = 5985
HTTPS = 5986
IPv4Filter = *
IPv6Filter = *
EnableCompatibilityHttpListener = false
EnableCompatibilityHttpsListener = false
CertificateThumbprint
AllowRemoteAccess = true
Winrs
AllowRemoteShellAccess = true
IdleTimeout = 7200000
MaxConcurrentUsers = 10
MaxShellRunTime = 2147483647
MaxProcessesPerShell = 25
MaxMemoryPerShellMB = 1024
MaxShellsPerUser = 30
EDIT:我设法让它发挥作用。首先,在詹金斯奴隶上,我必须运行:
winrm set winrm/config/client '@{AllowUnencrypted="true"}'
然后我将管道更改为:
powershell """
\$creds = Import-CliXml \$home\\creds.xml
Invoke-Command -computername ${SERVER} -scriptblock {iisreset /restart} -Authentication Basic -Credential \$creds
"""
where creds.xml
是之前生成的文件Get-Credentials | Export-CliXml creds.xml
.
这仍然无法解释为什么手动 PowerShell 和 Jenkins Slave 之间的行为不同。这是一个有点烦人的解决方法,但至少我可以继续。