Using PowerShell to examine virtual machine BIOS or firmware settings

As we all know, virtual machines are designed to be virtual analogs to physical computers. While it is sometimes tempting to think of a virtual machine as consisting primarily of a hardware allocation table (for memory mapping, etc.) and a virtual hard disk that contains the VMs operating system, there is actually a little bit more to the VM than that. Physical computers include firmware (which was referred to as the machine’s BIOS at one time), and Hyper-V virtual machines include a virtualized equivalent.

Before I begin

It isn’t exactly a secret that computers have evolved over time. The laptop that I am using to write this article has little in common with the 64KB Radio Shack Color Computer 2 that I used back in the 1980s. The same basic principle also holds true for Hyper-V virtual machines.

Hyper-V allows for the creation of Generation 1 and Generation 2 VMs. These two virtual machine generations differ significantly from one another in terms of the virtual hardware that they expose. Generation 1 VMs for example, use IDE virtual hard disks, and allow virtual machines to communicate with physical DVD drives. Generation 2 VMs, on the other hand, do not support the use of IDE virtual hard disks, nor do they support the use of physical DVD drives. Instead, Generation 2 virtual machines use SCSI virtual hard disks and emulated DVD drives.

Not only does hardware support differ between the two different generations of virtual machines, but so too does the virtual machine’s firmware emulation. Generation 1 virtual machines use emulated BIOS, while Generation 2 VMs use emulated firmware.

Virtual machine BIOS

The emulated BIOS for a Generation 1 VM is displayed within the Hyper-V Manager. As you can see in the figure, the virtual machine BIOS controls the boot order for the VM. In this case, the VM is configured to use a CD drive as the initial boot device, followed by an IDE based virtual hard disk, and then a legacy network adapter, and finally a floppy disk.

As is so often the case in Hyper-V however, the Hyper-V Manager does not expose everything. More often than not, you will find that the Hyper-V Manager exposes the most commonly used settings, while other settings exist beneath the surface, and are exposed only through PowerShell or possibly through supplementary tools such as System Center Virtual Machine Manager.

If we wanted to take a look at the virtual machine BIOS through PowerShell, we could do so by entering the Get-VMBios cmdlet, followed by the name of the virtual machine. As you would probably expect, this command causes PowerShell to display the boot order for the virtual machine. However, PowerShell also tells you whether the virtual machine is configured to automatically turn on numlock when the VM is booted.

Just as the Hyper-V Manager tends to only show basic settings, the same is also true of PowerShell. PowerShell initially only shows a couple of BIOS-related settings. However, if we dig just a little bit deeper, we can see all of the BIOS-related settings that are accessible. The way to do this is to use this command:

Get-VMBios <virtual machine name> | Select-Object *

Incidentally, the command listed above only works for Generation 1 VMs. If you try using this command on a Generation 2 VM, you will get an error. At any rate, the command produces the output shown in the next figure.

We could even take things a step further and manipulate the BIOS information directly through PowerShell. If for example, I wanted to automatically enable numlock on the VM, I could use this command:

Set-VMBios <virtual machine name> -EnableNumLock

Emulated firmware

As previously mentioned, Generation 2 VMs use emulated firmware rather than emulated BIOS. You can see what the firmware emulation looks like in the screenshot below. As was the case with the VM BIOS, the Hyper-V Manager allows you to use the firmware to control the virtual machine’s boot order.

Because Generation 2 VMs do not use BIOS emulation, you cannot use the Get-VMBios cmdlet to examine a Generation 2 VM. Instead, you will have to use the Get-VMFirmware cmdlet.

The Get-VMFirmware cmdlet reveals more information than the Get-VMBios cmdlet does. Whereas Get-VMBios basically just shows you the boot order and the state of the number lock, Get-VMFirmware shows the boot order, whether Secure Boot is being used, which template Secure Boot is using, the boot order, and the preferred network boot order.

As was the case with the Get-VMBios cmdlet, you can also view some extra configuration information by using the Get-VMFirmeare <virtual machine name> | Select-Object * cmdlet. You can see what this looks like in the next figure.

Unfortunately, you can’t use the Set-VMFirmware cmdlet to set the state of the number lock key, but you can use it to do other things. For example, you can use the Set-VMFirmware command to enable or to disable Secure Boot. To disable Secure Boot for a VM for example, you would use this command:

Set-VMFirmware <virtual machine name> -EnableSecureBoot Off

Modifying low-level virtual machine BIOS or firmware settings probably isn’t going to be the sort of thing that you will do every day. Even so, it is important for Hyper-V administrators to understand that in spite of what the Hyper-V Manager might lead you to believe, the virtual machine BIOS (or firmware) does more than just controlling the virtual machine’s boot order. It is also helpful to know how to check the BIOS and firmware settings, and to modify them if necessary. As you do, it is important to keep in mind that Hyper-V manages the settings for Generation 1 and Generation 2 separately, so you won’t be able to use PowerShell to apply a global configuration to all of your VMs happen to be the same generation.

Photo credit: Shutterstock