Hyper-V’s various GUI tools allow you to modify most of the common virtual machine settings. With the Hyper-V PowerShell module, you can modify a few more. Some settings, however, remain out of easy reach. One particular WMI class contains the setting for the virtual machine’s NumLock key setting and a handful of identifiers. Manipulating that specific class is unpleasant, even if you’re versed in WMI.

I’ve previously written PowerShell scripts to deal with these fields. Those scripts tend to be long, complicated, and difficult to troubleshoot. So, after taking some time to familiarize myself with the Management Interface API, I’ve produced a full-fledged graphical application so that you can make these changes more simply.

The application looks like this when run against my system:

VM Editor Main Screen

VM Editor Main Screen

The single shown dialog contains the entire application. Modeling after the design philosophy of Altaro Software, “ease-of-use” was my primary design goal. It’s a busy dialog, however, so a quick walkthrough might help you get started.

Advanced VM Settings Editor: Walkthrough

The screen is designed to work from left to right. You can use the screenshot above as a reference point, if you’d like, but it’s probably easier to install the application and follow along with the real thing.

Begin by choosing a host.

Choosing a Hyper-V Host

Use the drop-down/edit control in the top left. You can type the name of a Hyper-V host and press [Enter] or push the Refresh Virtual Machine List button to attempt to connect to a host by name. It does not work with IP addresses. You can use the Browse button to locate a system in Active Directory. I did code the browse functionality to allow you to pick workgroup-joined hosts. I did not test it for workgroup connectivity, so I don’t know (or care) if that part works or not.

If you installed the app to work with local virtual machines, enter a period (.), “LOCALHOST”, or the name of the local computer.

Loading the Virtual Machine List

Upon choosing a host, the contained virtual machines will automatically appear in the list box at the far left of the dialog. If none appear, you should also receive an error message explaining why. Use the Refresh Virtual Machine List to refresh the list items. The application does not automatically detect changes on the host, so you’ll need to use this if you suspect something is different (ex: a virtual machine has Live Migrated away).

A valid host must be selected for this section to function.

Loading the Current Settings for a Virtual Machine

Clicking on any virtual machine item in the list at the left of the dialog will automatically populate the settings in the center of the dialog. It will also populate the power state readout at the top right.

Clicking on the same virtual machine will reload its settings. If you have made any changes and not applied them, you will be prompted.

Making Changes to a Virtual Machine

There are six options to modify, and six corresponding fields.

  • Enable NumLock at Boot: This field is a simple on/off toggle.
  • Baseboard Serial Number
  • BIOS GUID: If you are PXE booting virtual machines, this field contains the machine UUID. This field requires 32 hexadecimal characters. Because there are multiple ways for GUIDs/UUIDs to be formatted, I opted to allow you to enter any character that you like. Once it has found 32 hexadecimal characters (digits 0 through 9 and letters A through F, case insensitive), it will consider the field to be validly formatted. Any other characters, including hexadecimal characters after the 32nd, will be silently ignored.
  • BIOS Serial Number
  • Chassis Asset Tag
  • Chassis Serial Number

The text fields besides the BIOS GUID are limited to 32 characters. WMI imposes the limit, not the application.

Viewing and Changing the Virtual Machine’s Power State

The power state is important because you cannot save changes to a virtual machine in any state other than Off. The current state is shown in the text box at the top right. Use the buttons underneath to control the virtual machine’s power state. Be aware that the Refresh State button is the only way to re-check what the virtual machine’s power state is without affecting any of the editable fields.

This application is not multi-threaded, so it will appear to hang on any long-running operation. The worst, by far, is the Graceful Shutdown feature.

Saving and Discarding Virtual Machine Changes

Use the Apply Changes and Reset Fields button to save any pending changes to the virtual machine or to discard them, respectively. If you attempt to save changes for a virtual machine that is not in the Off state, you will receive an error.

All of the error messages generated by the Apply Changes button are sent from WMI. I did not write them, so I may not be able to help you to decipher all of them. During testing, I occasionally received a message that the provider did not support the operation. When I got it, I just clicked the button again and the changes went through. However, I also stopped receiving that error message during development, so it’s entirely possible that it was just a bug in my code that was fixed during normal code review. If you receive it, just try again.

Usability Enhancements

The application boasts a couple of features meant to make your life a bit easier.

LOCALHOST Detection

As mentioned above, use a period (.), “LOCALHOST” or the local computer’s name to connect locally. I added some logic so that it should always know when you are connected locally. If it detects a local connection, the application will use DCOM instead of WinRM. Operations should be marginally faster. That said, I was impressed with the speed of the native MI binaries. If you’re accustomed to the delays of using WMI via PowerShell, I think you’ll be pleased as well.

However, I do have some concerns about the way that local host detection will function on systems that do not have WinRM enabled. If you can’t get the application to work locally, see if enabling WinRM fixes it (winrm qc at a command prompt or Enable-PSRemoting at an elevated PowerShell prompt).

Saving and Deleting Previously Connected Hosts

Once you successfully connect to a host, the application will remember it. If you don’t want a host in the list anymore, just hover over it and press [Delete].

If you’d like to edit the host list, look in %APPDATA%SironVMEditorvmhosts.txt. Each host is a single line in the text file. Short names and FQDNs are accepted.

Settings Validation Hints

As you type, the various fields will check that you are within ranges that WMI will accept. If you enter too many characters for any text field except BIOS GUID, the background of the text field will turn a reddish color. As long as you are within acceptable ranges, it will remain green. The BIOS GUID field will remain green as long as it detects 32 hexadecimal characters.

I realize that some people are blue-green colorblind and may not be able to distinguish between the two colors. Proper validation is performed upon clicking Apply Changes.

Clear Error Messages

One of the things that drives me nuts about software developers is the utter gibberish they try to pass off as error messages. “Sorry, there was an error.” How useless is that? Sure, I know first hand how tiresome writing error messages can be. But, I figure, I voluntarily wrote this app. None of you made me do it. So, it’s not right to punish you with cryptic or pointless messages. Wherever possible, I wrote error messages that should clearly guide you toward a solution. Any time that I didn’t, it’s because I’m relaying a useless message from a lower layer, like “unknown”.

Application Security

In general, I have left security concerns to the Windows environment. The application runs under your user context, so it cannot do anything that you do not already have permission to do. WMI throws errors on invalid input, so sneaking something by my application won’t have much effect. WMI communications are always encrypted, and I can see it loading crypto DLLs in the debugger.

I did instruct the application to securely wipe the names and IDs of all virtual machines from memory on exit. I’m not certain that has any real security value, but it was trivial to implement so I did it.

Potential Future Enhancements

The application does everything that it promises, so I’m not certain that I’ll update it for anything beyond bug fixes. There are a few things that I already have in mind:

  • Multi-threaded/asynchronous. The application appears to hang on long-running operations. They aren’t usually overly annoying so it didn’t seem worth it to delay version 1 to add the necessary infrastructure.
  • Automatic detection of state changes. The API has techniques for applications to watch for changes, such as to power states. These would be nice, but they also require enough effort to implement that they would have delayed version 1.
  • Other visual indicators. I was brainstorming a few ways to give better visual feedback when a field contained invalid data, but ultimately decided to proceed along so that I could release version 1.
  • Other settings. This is already a very busy dialog. I can’t imagine widening its net without major changes. But, maybe this app does need to grow.

I think that a lot of these enhancements hinge on the popularity of the app and how much their absence impacts usability. The program does what it needs to do today, so I hate to start tinkering too much.

System Requirements

Testing was extensively done using Windows 7 and Windows 10 clients against Windows Server 2012 R2 Hyper-V hosts. Some testing was done on other platforms/clients. The supported list:

  • Hyper-V Hosts
    • Windows Server 2012 (not directly tested at all)
    • Windows Server 2012 R2
    • Windows Server 2016
    • Windows 8/8.1 (not directly tested at all)
    • Windows 10 (not directly tested at all)
  • Clients
    • Windows 7
    • Windows 8/8.1 (not directly tested at all)
    • Windows 10
    • Windows Server 2008 R2
    • Windows Server 2012 (not directly tested at all)
    • Windows Server 2012 R2
    • Windows Server 2016

Software Prerequisites

The client and the server must be running at least the Windows Management Framework version 3.0. The version of PowerShell on the system perfectly matches the version of WMF, so you can run $PSVersionTable at any command prompt to determine the WMF level. The MSI and EXE installers will warn you if you do not meet this requirement on the client. The standalone executable will complain about a missing MI.dll if the framework is not at a sufficient level. WMF 3.0 shipped with Windows 8 and Windows Server 2012, so this is mostly a concern for Windows 7 and Windows Server 2008 R2.

The client must have at least the at least the Visual Studio 2015 C++ Redistributable installed. I did not intentionally use any newer Windows/Windows Server functionality, so earlier versions of the redistributable may work. If you use either of the installers, a merge module is included that will automatically add the necessary runtime files. If you use the EXE-only distribution and the required DLLs are not present, the application will not start. It also will not throw an error to tell you why it won’t start.

Downloading the Advanced VM Settings Editor for Hyper-V

You can download the application right from here. I have provided three packages.

  • Get the MSI package: SetupVMEditor1.0.0.msi.
  • Get the installer EXE: SetupVMEditor1.0.0.exe
  • Get the directly runnable EXE: VMEditor-PlainEXE.
    • Note: You must have the Windows Management Framework version 3.0 installed. You will receive an error about a missing “MI.dll” if this requirement is not met.
    • Note if not using an installer: You must have at least the Visual Studio 2015 C++ Redistributable installed. The application will not even open if the required DLLs are not present on your system.

Support, Warranty, Disclaimer, and All That

I wrote this application, not Altaro. There’s no warranty, there’s no promises, there’s no nothing. It’s 100% as-is, what you see is what you get, whatever happens, happens. It might do something that I didn’t intend for it to do. It might do things that you don’t want it to do. Do not call Altaro asking for help. They gave me a place to distribute my work and that’s the end of their involvement.

I’ll provide limited support here in the comments. However, my time is limited, so help me to help you. I will not respond to “it didn’t work” and “I tried but got an error the end” messages. If you got an error, tell me what the error was. Tell me your OS. Tell me what I can do to reproduce the error.

I am specifically excluding providing support for any problems that arise from attempting to use the application on a workgroup-joined host. I only test in domain environments. If it happens to work in a workgroup, that’s great! If not, too bad!