首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Powershell调用-命令远程手动工作,但不是从Jenkins

Powershell调用-命令远程手动工作,但不是从Jenkins
EN

Stack Overflow用户
提问于 2018-04-09 19:29:53
回答 2查看 6.9K关注 0票数 3

我遇到了一种非常奇怪的情况,在从Windows 2012 R2手动运行时,相同的命令可以工作,而不是从运行在同一服务器上的Jenkins从进程中运行。

首先,手动运行的输出,管理PowerShell窗口:

代码语言:javascript
复制
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管道代码的相关片段:

代码语言:javascript
复制
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运行时的输出:

代码语言:javascript
复制
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配置:

代码语言:javascript
复制
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

在网络服务器上:

代码语言:javascript
复制
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

编辑:我是经过一段时间才开始工作的。首先,在詹金斯奴隶问题上,我不得不逃跑:

winrm set winrm/config/client '@{AllowUnencrypted="true"}'

然后,我将管道改为:

代码语言:javascript
复制
powershell """
    \$creds = Import-CliXml \$home\\creds.xml
     Invoke-Command -computername ${SERVER} -scriptblock {iisreset /restart} -Authentication Basic -Credential \$creds
"""

其中creds.xml是以前用Get-Credentials | Export-CliXml creds.xml生成的文件。

这仍然不能解释为什么手动PowerShell和Jenkins奴隶之间的行为是不同的。这是一个恼人的解决办法,但至少我可以继续。

EN

回答 2

Stack Overflow用户

发布于 2018-04-10 10:06:25

您可能遇到了Jenkins的远程执行脚本限制(这里的原因是安全性)。您需要配置Jenkins服务器,使其能够“正常”运行脚本,但始终必须添加凭据。

从powershell命令行运行的脚本使用win-cm8utd1qfnc\administrator的默认凭据,因此如下所示将如您所写:

代码语言:javascript
复制
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运行Powershell时--这是一个本质上的插件--您就达到了按设计安全性的限制。您不希望在管理帐户中运行“野生”脚本。

我在这个主题上找到的最合理的指南是这里 (以下摘录自该页):

远程执行Powershell脚本/命令

上面的作业在Jenkins服务器本身上创建一个文本文件。为了设置远程Powershell脚本,我们首先需要配置Jenkins服务器以执行远程Powershell脚本。以启用远程Windows计算机到Jenkins服务器上的WS受信任列表。在Jenkins服务器上的Powershell窗口上执行以下命令。命令将将所有远程计算机添加到受信任的列表中。 Set-Item WSMan:\localhost\Client\TrustedHosts * 除了这些命令之外,我们还需要启用远程脚本执行。为了启用Powershell脚本的执行,在Jenkins服务器上的Powershell窗口中远程执行以下命令。 Set-ExecutionPolicy RemoteSigned –Force 我们将不得不安装一个名为EnvInject插件的新插件来传输变量,例如密码。 登录到Jenkins并导航到Manage > Manage,单击“可用”选项卡,然后在“筛选器”框中输入EnvInject,选择显示插件的名称,立即选择PowerShell插件下载,重新启动后安装 创建一个重新启动Windows时间服务的作业: 在Jenkins接口上,单击New为作业名称输入远程Powershell脚本。选择Freestyle项目勾选此生成是参数化的。创建以下参数类型: String参数名称: ServerIp/Hostname描述:远程计算机的IP地址。类型:字符串参数名称: UserName类型:密码参数名称:现在密码,单击“添加参数”列表并选择“选择参数”。在“选项”文本框中输入新行上的选项。另外, 对上述备选方案提供说明:

下面的脚本基于上面的链接,但是我不喜欢使用的纯文本,所以我决定重写它以使用Powershell的SecureString

首先存储您的管理密码:

代码语言:javascript
复制
read-host -AsSecureString | ConvertFrom-SecureString | Out-File C:\<your_path>\securestring.txt

然后让脚本:

代码语言:javascript
复制
# Configure build failure on errors on the remote machine similar to set -x on bash script 
$ErrorActionPreference = 'Stop'  

# Create a PSCredential Object using the "Username" and "Password" variables created on job 
$password = Get-Content 'C:\<your_path>\securestring.txt' | ConvertTo-SecureString
$creddentials = New-Object System.Management.Automation.PSCredential -ArgumentList $env:UserName, $password

# It depends on the type of job you are executing on the remote machine as to if you want to use "-ErrorAction Stop" on your Invoke-Command. 
Invoke-Command -ComputerName $env:Computer -Credential $credentials -ScriptBlock { Restart-Service -Name W32Time }
票数 1
EN

Stack Overflow用户

发布于 2018-12-24 14:22:10

参见这个问题:使用Powershell和Jenkins进行远程访问

需要将服务用户从本地系统更改为管理员。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49740313

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档