Почему при копировании виртуальной машины не сохраняются сетевые настройки?

За последние пару месяцев мне несколько раз задавали вопрос, почему при копировании виртуальной машины сбрасываются настройки сетевых интерфейсов. Если честно, изначально я не придавал ему большого значения, но когда он прозвучал из нескольких независимых источников — решил разобраться. В Virtual Server 2005 мы просто копировали файлы виртуальных дисков (VHD) и настроек виртуальных машин (VMC) на любой другой сервер, или даже просто создавали новую ВМ на основе старого виртуального диска — и все настройки внутри ВМ сохранялись. В Hyper-V для этого потребуется экспортировать виртуальную машину отдельной командой, а затем импортировать ее соответствующим образом. Но иногда этой процедурой приходится пренебречь и просто скопировать файл виртуального диска. Например, когда этот файл вам передали на внешнем носителе, не экспортировав предварительно ВМ. Что же произойдет в этом случае? Вы создадите новую ВМ, включите ее, она загрузится — но все сетевые настройки: адрес IP, серверы WINS и DNS, суффикс подключения будут потеряны. Почему это происходит? Сразу скажу, новая модель безопасности и изоляции ВМ в Hyper-V тут ни при чем. Подумайте — что будет, если вы в физическом сервере замените сетевую карту? Или даже перенесете жесткий диск в другой сервер — что, собственно, и происходит при создании новой ВМ на основе имеющегося файла виртуального диска. Вот тут-то и зарыта собака! Случится то же самое: потеряются настройки подключения. Ведь изменится GUID сетевой карты, и для нового устройства ОС создаст новое подключение. Давайте разберемся, что с этим можно сделать, куда исчезает старое подключение, исчезает ли вообще и можно ли вернуть настройки обратно.

Предположим, что я получил виртуальный диск с виртуальной машиной Windows Server 2008. Разумеется, получил без остальных экспортированных настроек. Я создал новую виртуальную машину (она получила новые GUID и SID) и настроил ее на использование полученного мною диска в качестве загрузочного. Загрузив ОС, я вижу, что сетевые настройки сбросились в состояние по умолчанию. Однако я знаю, какие именно настройки у этой ОС должны быть — и присваиваю сетевому интерфейсу те же адреса IP, которые были настроены ранее. И неожиданно получаю следующее предупреждение.

Интересно! При попытке применить настройки, ОС предупреждает меня о том, что они уже заданы для другого сетевого интерфейса. Но ведь интерфейс у нас всего один! Значит, Windows «помнит» о старом интерфейсе — и его настройках. Существует даже статья Базы знаний номер 315539, которая рассказывает о том, как эту информацию можно удалить. Она рассказывает про Windows XP, но процедура аналогична и для более новых версий ОС.

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

Что у нас имеется на данный момент:

  • Виртуальный диск от машины с Windows Server 2008. В настройках ее сетевого интерфейса был задан адрес IP 192.168.1.8.
  • Новая виртуальная машина с одним синтетическим сетевым интерфейсом, к которой мы добавили этот диск.
  • ОС в виртуальной машине задала настройки по умолчанию для нового сетевого подключения «Local Area Connection N» в списке (Network Connections, ncpa.cpl). Причем N здесь — это порядковый номер, и он отличается от того, что был в исходной ВМ.

Теперь пройдем по шагам, предлагаемой в статье 315539. Запустим командную строку с повышенными привилегиями (Elevated Command Prompt, то есть выберем пункт «Запустить как Администратор» в контекстном меню ярлыка) и выполним в ней следующие команды.

  • set devmgr_show_nonpresent_devices=1;
  • start devmgmt.msc.

Затем в меню «View» выберем пункт «Show hidden devices» и раскроем в дереве секцию «Network Adapters».

Обратим внимание на то, что в теперь в списке присутствуют два сетевых интерфейса. Действующий (выделен на скриншоте) и отсутствующий старый (сразу под ним). Сравним свойства текущего интерфейса и старого.

Глядите, подсвеченные GUID у интерфейсов отличаются. У моей текущей конфигурации GUID начинается на 2a55878c.... В принципе, эти GUID можно посмотреть и в реестре ВМ в дебрях HKLM\SYSTEM\CurrentControlSet\Control\DeviceClasses.

Теперь немного технической информации. Настройки всех виртуальных машин хранятся в формате XML в виде файлов, которые по умолчанию расположены на системном диске в каталоге \programdata\microsoft\windows\hyper-v\virtual machines. Редактирование этих файлов вручную — это совершенно не поддерживаемая операция. Для этого потребовалось бы производить такие сомнительные манипуляции, как остановка служб и махинации с правами. Да к тому же формат этих файлов может быть изменен в будущем без каких-либо уведомлений и предупреждений. Однако, изучить файл в режиме чтения можно смело. Ниже я привожу пример своего файла, где выделенный элемент <ChannelInstanceGuid> как раз задает GUID интерфейса — 2a55878c-e56f-41a6-bf6e-12efd752a202.

<_66f9a54b-b048-40ec-8f61-9efd82feffc9_>

  <ChannelInstanceGuid type="string">{2a55878c-e56f-41a6-bf6e-12efd752a202}</ChannelInstanceGuid>

  <FriendlyName type="string">Network Adapter</FriendlyName>

  <IsConnected type="bool">True</IsConnected>

  <MacAddress type="string">00-15-5D-01-01-15</MacAddress>

  <MacAddressIsStatic type="bool">False</MacAddressIsStatic>

  <PortName type="string">67cd48a1-9b19-455e-b66e-745d0d4e5737</PortName>

  <SwitchName type="string">a27d201a-a5f4-43e7-9b56-43788a13d96a</SwitchName>

</_66f9a54b-b048-40ec-8f61-9efd82feffc9_>

Теперь вы примерно представляете себе, где находится «корень всех бед». Если вы вручную замените здесь GUID на старый (в моем случае — на тот, что начинается на f05ba01d...), то получите в ОС старые настройки. Однако, поскольку эта операция не поддерживается, я такого советовать не буду. А вместо этого предложу вам разобраться с WMI — почитав о модели WMI в Hyper-V и исследовав массив Msvm_SyntheticEthernetPortSettingData.VirtualSystemIdentifiers[]. Готовых сценариев предлагать не буду — может быть, кто-то попробует справиться с такой задачкой самостоятельно?

А если вы просто захотите посмотреть старые настройки из новой ВМ — вдруг вы их не знаете — обратите внимание на ветвь реестра HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces в ОС вашей виртуальной машины. Все необходимые сведенья можно извлечь оттуда.