Как предотвратить отключение numlock в виртуальной машине Hyper-V (Windows 11, поколение 2)

Вопрос или проблема

У меня есть цифровая клавиатура, которую я использую для ввода чисел. Обычно, когда моя Windows загружается (Windows 11 Pro 10.0.22621), NumLock включен.
Однако, когда я запускаю виртуальную машину Hyper-V (gen 2), это отключает NumLock, и это действительно раздражает.
Есть ли способ предотвратить отключение NumLock при запуске виртуальной машины?

Я столкнулся с той же проблемой и перепробовал различные решения, чтобы исправить ее, но ни один из найденных в интернете подходов действительно не помог: ключ реестра:

В конце концов, я нашел только одно рабочее решение для устранения проблемы с NumLock. Необходимо создать скрипт PowerShell на виртуальной машине, например, назовем его ‘NumlockEnable.ps1’ с следующим содержимым:

$WshShell = New-Object -ComObject WScript.Shell
if ([console]::NumberLock -eq $false) {
   $WshShell.SendKeys("{NUMLOCK}")
}

И сделать так, чтобы скрипт выполнялся при входе в систему, например, используя Group Policy Object (GPO), согласно инструкциям.

Также, в моем случае (гостевая ОС Windows 10), следующий ключ реестра должен быть установлен на следующее значение

[HKEY_USERS\.DEFAULT\Control Panel\Keyboard]
"InitialKeyboardIndicators"="80000002"

P.S. Конечно, это костыль, но все остальное не работает

После многих часов обратного проектирования сборок ‘Microsoft.HyperV.PowerShell.Cmdlets’ и ‘Microsoft.HyperV.PowerShell.Objects’, я наконец нашел лучший способ сделать так, чтобы виртуальная машина Hyper-V “включала NumLock по умолчанию”.

TL;DR; Вот код PowerShell:

function Set-VMNumLock {
  param(
    [Microsoft.HyperV.PowerShell.ComputeResource]$vm,
    [bool]$NumLockEnabled
  )
  # Получаем объект настроек с помощью рефлексии
  $ComputerResourceType = [Microsoft.HyperV.PowerShell.ComputeResource]
  $SettingField = $ComputerResourceType.GetDeclaredField("_settings")
  $settingUpdater = $SettingField.GetValue($vm)

  $vmComputerSystemView = $settingUpdater.GetData([Microsoft.HyperV.Powershell.UpdatePolicy]::EnsureUpdated)
  $vmComputerSystemView.BiosNumLock = $NumLockEnabled
  $vmComputerSystemView.Put()
}

Примечание: Это настройка не может быть изменена, когда виртуальная машина включена.

Вот как использовать это

$vm = Get-VM -VMName “SampleVM”
Set-VMNumLock -vm $vm -NumLockEnabled $true

Полная история

Сначала я был вдохновлен неким кодом PowerShell на основе “WMI”/”CIM” с другого сайта. (Не уверен, могу ли я упоминать гиперссылки на других сайтах здесь). Хотя этот код не работает, но он показал мне основное, о том, “где хранится настройка NumLock”.

В итоге я декомпилировал ‘Microsoft.HyperV.PowerShell.Cmdlets.dll’ и ‘Microsoft.HyperV.PowerShell.Objects.dll’. В классе Microsoft.HyperV.PowerShell.Commands.SetVMFirmware, вы найдете все определено в Microsoft.HyperV.PowerShell.VMFirmware. Углубляясь дальше, его основная структура данных была
Microsoft.Virtualization.Client.Management.IVMComputerSystemSetting (На самом деле это общая структура для виртуальных машин Gen1 и Gen2), есть булево свойство, называемое BiosNumLock.

Фактически, программист Microsoft всего на один шаг от поддержки NumLock в Set-VMFirmware командлете.

В классе VMBios, есть свойство, называемое NumLockEnabled, которое по сути обертка для этого BiosNumLock

namespace Microsoft.HyperV.PowerShell;

public sealed class VMBios : VMComponentObject, IUpdatable
{
    private readonly DataUpdater<IVMComputerSystemSetting> m_VMSetting;

    public bool NumLockEnabled
    {
        get
        {
            return m_VMSetting.GetData(UpdatePolicy.EnsureUpdated).BiosNumLock;
        }
        internal set
        {
            m_VMSetting.GetData(UpdatePolicy.None).BiosNumLock = value;
        }
    }
    // ... другой код 

Если Microsoft хочет поддерживать NumLock в виртуальных машинах Gen2, они просто вставляют это свойство в класс VMFirmware. Я не знаю, почему они слишком ленивы, чтобы это сделать.

.

Ответ или решение

Проблема с отключением NumLock при запуске виртуальной машины Hyper-V в Windows 11 может быть весьма неприятной, особенно если работа с цифровой клавиатурой является частью вашей повседневной деятельности. Чтобы понять, как можно решить эту проблему, рассмотрим несколько аспектов, связанных с работой Hyper-V и управления указанной функцией.

Теория

Что такое Hyper-V и как он работает?

Hyper-V — это технология виртуализации от Microsoft, интегрированная в Windows Server и Windows 10/11, позволяющая запускать несколько виртуальных машин (ВМ) на одном физическом сервере. Каждая виртуальная машина действует как автономная система, что позволяет гибко управлять различными операционными системами и приложениями на одном устройстве.

Проблема с NumLock

Проблемы с NumLock при работе с виртуальными машинами могут возникать вследствие особенностей взаимодействия компонентов Hyper-V и настройки BIOS виртуальной машины (или эквивалента для систем Gen 2). Hyper-V генерирует отдельную среду ввода-вывода, и нередки случаи, когда настройки по умолчанию не соответствуют вашим предпочтениям или настройкам хост-системы.

Пример

Первоначальные решения

Некоторые пользователи, как вы описали, пробовали использовать скрипты PowerShell для исправления этой проблемы. Представленный скрипт PowerShell проверяет состояние NumLock и при необходимости включает его:

$WshShell = New-Object -ComObject WScript.Shell
if ([console]::NumberLock -eq $false) {
   $WshShell.SendKeys("{NUMLOCK}")
}

Этот подход с использованием PowerShell достаточно прост и может быть автоматизирован через Политику групп (GPO) для запуска при входе в систему, что позволяет автоматически включать NumLock при каждом запуске виртуальной машины.

Более глубокий подход

Расширенное решение, представленное сообществом, включает использование собственных возможностей Hyper-V через рефлексию, чтобы изменить внутренние настройки виртуальной машины, включая свойство BiosNumLock.

Для этого в PowerShell создается функция Set-VMNumLock, которая извлекает настройки объекта виртуальной машины и модифицирует их:

function Set-VMNumLock {
  param(
    [Microsoft.HyperV.PowerShell.ComputeResource]$vm,
    [bool]$NumLockEnabled
  )
  # Получаем объект настроек с помощью рефлексии
  $ComputerResourceType = [Microsoft.HyperV.PowerShell.ComputeResource]
  $SettingField = $ComputerResourceType.GetDeclaredField("_settings")
  $settingUpdater = $SettingField.GetValue($vm)

  $vmComputerSystemView = $settingUpdater.GetData([Microsoft.HyperV.Powershell.UpdatePolicy]::EnsureUpdated)
  $vmComputerSystemView.BiosNumLock = $NumLockEnabled
  $vmComputerSystemView.Put()
}

Этот метод позволяет непосредственно управлять настройками через внутренние API Hyper-V, что является более устойчивым решением при наличии доступа к необходимой среде и инструментам.

Применение

Как использовать

Чтобы применить данное решение, сначала необходимо выключить виртуальную машину и затем выполнить следующие команды в PowerShell:

$vm = Get-VM -VMName “SampleVM”
Set-VMNumLock -vm $vm -NumLockEnabled $true

Обратите внимание, что изменение собственных настроек невозможно, когда виртуальная машина включена. Поэтому сначала необходимо убедиться, что все изменения применяются, когда машина отключена.

Дополнительные рекомендации

  • Проверка и настройка реестра: на гостевой ОС рекомендуется задать ключ реестра для начальной настройки NumLock:
[HKEY_USERS\.DEFAULT\Control Panel\Keyboard]
"InitialKeyboardIndicators"="80000002"
  • Убедитесь, что все обновления Windows и Hyper-V установлены, так как они могут содержать исправления функциональности и управления оборудованием.

Заключение

Данная проблема решаема несколькими способами в зависимости от уровня доступа и возможностей вашей системы. Предложенные решения обеспечивают как простые патчи с использованием PowerShell скриптов, так и более комплексные подходы через глубокую настройку Hyper-V. Рекомендуется протестировать оба варианта, чтобы определить, какой из них лучше всего подходит для вашей специфической конфигурации. Обслуживайте рабочую среду с регулярными резервными копиями и тестами, чтобы минимизировать простои и потенциальные проблемы с функциональностью NumLock.

Оцените материал
Добавить комментарий

Капча загружается...