Определение платформы виртуализации из сценария

Недавно мне понадобился способ, позволяющий отличать виртуальные машины Virtual Server 2005 от виртуальных машин Hyper-V при применении групповых политик. Также возможна ситуация, когда понадобится определить платформу виртуализации для установки программного обеспечения — например, для обновления компонентов виртуализации. Возможность узнать из виртуальной машины, какая платформа виртуализации используется, также может потребоваться для задач инвентаризации. Например, в тех сценариях, когда «родительская» система по соображениям безопасности не включена в домен или даже не имеет доступа в корпоративную сеть. (При этом сеть может быть доступна лишь из самих виртуальных машин).

Многие ли из вас помнят наизусть, какие платформы виртуализации используются на тех или иных серверах вашей сети (считая, что их много)? Какая версия Hyper-V, актуален ли выпуск Virtual Server 2005 (R2, R2 SP1…), установлены ли в виртуальной машине текущие компоненты интеграции Hyper-V или Virtual Machine Additions (для VS2005)? В принципе, ничто не мешает нам определять и сторонние платформы виртуализации — как и версии используемых ими компонентов.

Проведя исследование в Интернете и прочитав практически все, что Live Search знает по данной теме, я пришел к следующим выводам. Решения, предлагаемые большинством авторов, основаны на выполнении некого компилированного бинарного кода — что на, мой взгляд, слишком сложно и затрудняет модификацию таких инструментов. Другой сравнительно распространённый метод — проверка строки «Manufacturer» (Производитель) класса WMI «Win32_BaseBoard», в котором описаны свойства материнской платы. Этот способ меня бы вполне устроил — однако, как для всех версий VS2005/VPC, так и для Hyper-V результат такой проверки оказывается одинаков: «Microsoft Corporation». А это не позволяет отличить платформы виртуализации друг от друга. Другие атрибуты этого класса также не дают ничего полезного.

Итак, в надежде найти зерно истины я вооружился WMICodeCreator и начал копать репозиторий WMI в различных виртуальных машинах. Заняло это гораздо меньше времени, чем поиск в Интернете — подходящий класс был быстро найден: «Win32_SystemBIOS». Строковой атрибут «PartComponent» несет в себе много дублируемой информации о BIOS вашей ВМ. Самое интересное хранится в конце строки «Version». Проведя несколько часов за переустановками разных версий платформ виртуализации я составил для себя некую табличку, на основании которой написал итоговый сценарий. Он проверяет строку «PartComponent» и — при запуске в виртуальной машине на одной из известных мне платформ — возвращает информацию о платформе виртуализации. Очевидно, что сценарий может не просто возвращать текстовое значение, а выполнять любые другие задачи в зависимости от текущей версии платформы. На данный момент мне известны следующие значения строки Version:

Платформа виртуализации Возвращаемое значение

Hyper-V Beta/RC0

VRTUAL - 1000831

Hyper-V RC1

VRTUAL - 5000805

VS2005/VPC2004

A M I - 8000314

VS2005 R2

A M I - 9000520

VS2005 R2 SP1/VPC2007

A M I - 2000622

VMware (все испробованные продукты и версии)

PTLTD - 6040000

Parallels Workstation

UNKNOWN

Как видите, при помощи несложного сценария можно отличать разные версии Virtual Server 2005 друг от друга и даже разные сборки Hyper-V. Последний я проверял в версиях RC0 / RC1 Escrow / RC1. Если у вас остались версии CTP или Beta — проверьте в них и мне дайте знать о результате. Наличие и версия установленных Integration Components или VMAdditions на результат не влияет. Для VMware я проверял следующие продукты: ESX Server 2.x и 3.x, GSX Server, Server, Workstation из-под Windows, Linux и Mac OS X — везде строка была одинаковой. Я знаю и о backdoor, который позволяет из виртуальной машины VMware узнать версию платформы виртуализации. Но известный мне способ его использования требует запуска скомпилированного на ассемблере кода, так что он уже выходит за определенные мной рамки. Если вы знаете способ использовать этот backdoor с помощью ключей реестра или репозитория WMI — напишите в комментариях, мне будет очень интересно. Для Parallels я проверял свой сценарий на версиях 2.х под Windows. Результат для Parallels Desktop (Mac OS X) добавлю завтра.

Если сценарий обнаруживает неизвестное значение — предполагается, что вы запустили его на физическом компьютере, а не в виртуальной машине. Однако при этом сценарий выведет значение строки Version, чтобы вы могли добавить в обработку и его — если это все-таки некий неизвестный мне тип ВМ. (В этом случае обязательно напишите в комментариях, мне тоже это очень интересно).

Полный текст сценария, определяющего платформу виртуализации, смотрите во вложении. Здесь я приведу его небольшой фрагмент, который просто выводит значение строки «PartComponent» класса «Win32_SystemBIOS» текущей системы — физической или виртуальной. Значение в кавычках в конце строки после слова «Version=» — это и есть то, что позволит отличить платформы виртуализации друг от друга. Найдете неизвестные мне значения — комментируйте.

strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")

Set colItems = objWMIService.ExecQuery( _

"SELECT * FROM Win32_SystemBIOS",,48)

For Each objItem in colItems

Wscript.Echo "PartComponent: " & objItem.PartComponent

Next

Если эта тема окажется вам интересна — ее можно будет развить, написав готовые фильтры WMI для использования с объектами групповых политик (GPO). Это позволит применять те или иные политики в зависимости от используемой платформы виртуализации, не запуская никаких сценариев и не требуя перезагрузки виртуальной машины.

DefineVM_BIOS.vbs