如何通过命令行检查VirtualBox VM是否未在Windows上运行



我正在从事一个 Jenkins 项目,以使用用户提供的参数远程启动和关闭特定 VM。

我已经设法找到了一种方法来确定指定的虚拟机是否已启动并正在运行并准备好接受进一步的说明,但我还没有找到一种方法来确定指定的虚拟机是否已关闭电源。

构建步骤中使用的当前代码如下:

@ECHO OFF
SETLOCAL EnableDelayedExpansion
ECHO Shutting down VM %VM% on Host %computername%...
"C:Program FilesOracleVirtualBoxVBoxManage.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

逻辑是这样的:

  1. 发送controlvm命令以执行目标虚拟机的 ACPI 关闭。
  2. 使用FOR循环访问正在运行的 VM 列表,以查看目标 VM 是否仍在运行。
  3. 如果目标 VM 仍在运行,请不要执行任何操作,并返回到 :LOOP 的开头并重新检查,直到结果更改。
  4. 如果"正在运行的 VM"列表中不再显示目标 VM,请将此生成步骤视为成功。

主要问题是:LOOP条款中的FOR语句。在构建步骤的启动部分,我可以使用VboxManage list runningvms来确定是否列出了指定的 VM,从而对其进行处理,并指示用于启动指定 VM 的 Jenkins 构建成功。

但是,我注意到,一旦通过前面的controlvm命令将目标 VM 从正在运行的 VM 列表中删除,FOR语句的整个DO部分根本不执行任何操作。它没有设置VM_State=%%a,一方面,它没有做我在FOR语句中抛出的任何其他事情。这会导致:LOOP无限循环,因为唯一的条件检查器不会触发。

问:是否有任何方法可以确定特定名称的虚拟机是否已关闭电源?

笔记:

  • Jenkins的VirtualBox插件与当前的VirtualBox版本(5.1.30(不兼容。
  • Jenkins 版本是 2.122。
  • 上面的代码经过测试,在目标机器和我自己的机器上作为独立的.bat文件运行时,行为相同。
  • 所有涉及的系统都在 Windows 10 v1803 上。

这在 Windows 10 上对我有用,希望对您有所帮助!

@ECHO OFF
SETLOCAL EnableDelayedExpansion
ECHO Shutting down VM %VM% on Host %computername%...
"C:Program FilesOracleVirtualBoxVBoxManage.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 FilesOracleVirtualBoxVBoxManage.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.

最新更新