我正在开发Jenkins项目,使用用户提供的参数远程启动和关闭特定的VM。
我已经设法找到一种方法来确定指定的VM已启动并正在运行并准备好进一步说明,但我还没有找到一种方法来确定指定的VM已关闭电源。
构建步骤中使用的当前代码是:
@ECHO OFF
SETLOCAL EnableDelayedExpansion
ECHO Shutting down VM %VM% on Host %computername%...
"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" controlvm %VM% acpipowerbutton
ECHO %ERRORLEVEL%
IF ERRORLEVEL 1 EXIT /B 1
:LOOP
WAITFOR /T 10 VMtoShutDown 2>NUL
FOR /f %%a IN ('VBoxManage list runningvms ^| FINDSTR %VM%') DO SET VM_State=%%a
IF [!VM_State!] EQU [] (
ECHO %VM% is not running.
EXIT /b 0
)
GOTO LOOP
逻辑是:
controlvm
命令以执行目标VM的ACPI关闭。FOR
遍历正在运行的VM列表,以查看目标VM是否仍在运行。主要问题是FOR
子句中的:LOOP
语句。在构建步骤的Startup部分中,我可以使用VboxManage list runningvms
来确定是否列出了指定的VM,并因此处理它并指示Jenkins构建以启动指定的VM成功。
但是,我注意到,一旦目标VM通过早期controlvm
命令从正在运行的VM列表中删除,DO
语句的整个FOR
部分就不会什么都不做它没有为{1}设置VM_State=%%a
,并且它没有做我在FOR
语句中抛出的任何其他内容。这导致:LOOP
无限循环,因为唯一的条件检查器不会触发。
问题:有没有办法确定特定名称的VM是否已关机?
注意:
答案 0 :(得分:0)
这在Windows 10上对我有效,希望对您有所帮助!
@ECHO OFF
SETLOCAL EnableDelayedExpansion
ECHO Shutting down VM %VM% on Host %computername%...
"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" controlvm %VM% acpipowerbutton
ECHO VirtualBox command return code: %ERRORLEVEL%
IF ERRORLEVEL 1 EXIT /B 1
:LOOP
REM Sleep for 1 second by using a ping hack :)
ping -n 2 127.0.0.1 > nul
"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" showvminfo %VM% | findstr /c:"powered off" >NUL
IF %ERRORLEVEL% EQU 0 GOTO END
echo VM %VM% not powered off yet...
GOTO LOOP
:END
echo VM %VM% powered off.