简体   繁体   English

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

[英]How to check via command line if a VirtualBox VM is not running on Windows

I am working on a Jenkins project to remotely startup and shutdown a specific VM with user-supplied parameters. 我正在一个Jenkins项目中,以使用用户提供的参数远程启动和关闭特定的VM。

I have managed to find a way to determine that the specified VM is started up and running and ready for further instructions, but I have yet to find a way to determine that the specified VM has powered off. 我设法找到一种方法来确定指定的VM已启动并正在运行,并准备好进行进一步的说明,但是我还没有找到一种方法来确定指定的VM已关闭电源。

The current code used in the build step is this: 在构建步骤中使用的当前代码是这样的:

@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

The logic is this: 逻辑是这样的:

  1. Send controlvm command to perform ACPI shutdown of target VM. 发送controlvm命令以执行目标VM的ACPI关闭。
  2. Use FOR to iterate through a list of Running VMs to see if target VM is still running. 使用FOR遍历正在运行的VM列表,以查看目标VM是否仍在运行。
  3. If target VM is still running, don't do anything, and go back to the beginning of :LOOP and re-check until result changes. 如果目标VM仍在运行,则不执行任何操作,然后返回:LOOP的开头并重新检查,直到结果更改为止。
  4. If target VM is no longer seen in the list of Running VMs, consider this build step a success. 如果在“正在运行的虚拟机”列表中不再看到目标虚拟机,则认为此构建步骤成功。

The main problem is the FOR statement in the :LOOP clause. 主要问题是:LOOP子句中的FOR语句。 In the Startup portion of the build step, I can use VboxManage list runningvms to determine if the specified VM is listed, and thus process it as such and indicate that the Jenkins build to startup the specified VM is successful. 在构建步骤的“启动”部分中,我可以使用VboxManage list runningvms来确定是否列出了指定的VM,并以此方式对其进行处理,并表明可以成功启动用于启动指定VM的Jenkins构建。

However, I noticed that once the target VM is taken off the list of running VMs by way of the earlier controlvm command, the entire DO part of the FOR statement simply doesn't do anything. 但是,我注意到,一旦通过较早的controlvm命令将目标虚拟机从正在运行的虚拟机列表中删除, FOR语句的整个DO部分就什么都不做。 It doesn't set the VM_State=%%a , for one, and it doesn't do anything else I had thrown into the FOR statement. 它不会将VM_State=%%a设置为一个,也不会做我在FOR语句中抛出的其他任何事情。 This causes the :LOOP to keep looping infinitely as the only condition checker doesn't fire. 这导致:LOOP无限循环,因为唯一的条件检查器不会触发。

Question: Is there any way to determine if a VM of a particular name is powered off? 问题:是否可以确定特定名称的VM是否已关闭电源?

Notes: 笔记:

  • The VirtualBox plugin for Jenkins is incompatible with the current VirtualBox version (5.1.30). Jenkins的VirtualBox插件与当前的VirtualBox版本(5.1.30)不兼容。
  • The Jenkins version is 2.122. Jenkins版本是2.122。
  • The code above is tested to behave the same when running as a standalone .bat file on the target machine and on my own machine. 经过测试,以上代码在目标计算机和我自己的计算机上作为独立的.bat文件运行时的行为均相同。
  • All systems involved are on Windows 10 v1803. 涉及的所有系统均在Windows 10 v1803上。

This works for me on Windows 10, hope it helps! 这在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.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM