我一直在尝试使用 Jenkins 自动测试虚拟机,其中包括将新代码复制到虚拟机中,或者使用 Powershell 脚本将某些命令从主机运行到虚拟机中。
但是,我在 Jenkins Freestyle 和 Pipeline 项目中尝试对 hyper-V Windows 10 VM 使用“Invoke-Command”或“New-PSSession”时遇到了错误。
这是 Jenkins 运行的环境:
Windows Specifications:
Edition: Windows Server 2019 Standard
Version: 1809
OS build: 17763.379
Jenkins ver. 2.190.1
Hyper-V Manager: 10.0.17763.1
这是我在自由式项目的“Windows Powershell”构建步骤中编写的 Powershell 脚本:
# Win10-Clean is currently running and the credentials are for the Win 10 VM.
$ErrorActionPreference = "Stop"
$VMName = "Win10-Clean"
$username = "username"
$pwd = "password"
$secpasswd = ConvertTo-SecureString $pwd -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ("$username", $secpasswd)
Get-VM
Invoke-Command -Credential $mycreds -VMName $VMName -ScriptBlock {host}
我希望输出是:
Running as SYSTEM
Building on master in workspace G:\ci_server_1\jenkins\workspace\powershell-testing-ground
[powershell-testing-ground] $ powershell.exe -NonInteractive -ExecutionPolicy ByPass "& 'C:\Windows\TEMP\jenkins6936256398230803297.ps1'"
Name State CPUUsage(%) MemoryAssigned(M) Uptime Status Version
---- ----- ----------- ----------------- ------ ------ -------
Win10-Clean Running 0 1854 5.14:10:42.5100000 Operating normally 8.3
PSComputerName : Win10-Clean
RunspaceId : 56151e46-5772-458f-8f11-9beba5491bc2
Name : ServerRemoteHost
Version : 1.0.0.0
InstanceId : fe09fc40-8434-4a7c-903b-b7b2c3f88506
UI : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture : en-US
CurrentUICulture : en-US
PrivateData :
DebuggerEnabled : True
IsRunspacePushed : False
Runspace : System.Management.Automation.Runspaces.LocalRunspace
Finished: SUCCESS
但我得到的是:
Running as SYSTEM
Building on master in workspace G:\ci_server_1\jenkins\workspace\powershell-testing-ground
[powershell-testing-ground] $ powershell.exe -NonInteractive -ExecutionPolicy ByPass "& 'C:\Windows\TEMP\jenkins233354859509300046.ps1'"
An error has occurred which Windows PowerShell cannot handle. A remote session might have ended.
At C:\Windows\TEMP\jenkins233354859509300046.ps1:7 char:1
+ Invoke-Command -Credential $mycreds -VMName Build_VM -ScriptBlock {ho ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OpenError: (Build_VM:String) [], PSRemotingDataStructureException
+ FullyQualifiedErrorId : PSSessionStateBroken
Build step 'Windows PowerShell' marked build as failure
Finished: FAILURE
参考微软官方网页解决这个问题后,可能的原因有:
- 虚拟机存在但未运行
- 来宾操作系统不支持 PowerShell Direct
Powershell 在来宾中尚不可用:
- 操作系统尚未启动
- 操作系统无法正确启动
- 一些启动时间事件需要用户输入
- 当前版本中存在必须使用 -Credential 显式传递凭据的错误。运行 Restart-Service -Name vmicvmsession 作为解决方法。
但是,从 Jenkins 的输出来看,我一直在尝试连接的虚拟机是“正在运行”并且它已正确启动。
然后,我尝试直接从主机将“Invoke-Command”和“New-PSSession”插入虚拟机,并且能够连接到虚拟机。
我也在安装在 Windows 10 机器而不是 Windows Server 2019 的 Jenkins 中尝试了同样的事情,并且一切正常。
至于用户管理信息,运行Jenkins的登录用户既是“管理员”又是“hyper-v管理员”。
这些是我用来调试的一些参考资料,但我无法找出问题所在:
使用 PowerShell 和 Jenkins 进行远程访问,但我无法弄清楚这是如何工作的。
编辑:
我找到了解决这个问题的方法。请注意,这不是确定的解决方案,而是一种解决方法。
而不是运行Invoke-Command -Credential $mycreds -VMName $VMName -ScriptBlock {host}
,运行这个:
Invoke-Command -ComputerName "MyHostComputer" -ScriptBlock {Invoke-Command -Credential $mycreds -VMName $VMName -ScriptBlock {host}}
该命令本质上是invoke-commanding
进入主机并使用主机运行Invoke-Command
到 VM 中。
这绝对不是完美的解决方案,但在任何人有更好的解决方案之前,我都会先使用它。