Rate this post

Описание методов модификацииnnИтак, чтобы модифицировать средствами хоста виртуализации параметры гостевой ОС, необходимо каким-либо образом ей передать некую команду, которая должна вы-полниться в ее среде. Наиболее простой способ – исполь-зование штатных средств, в качестве таковых обычно вы-ступают средства интеграции, установленные в гостевой ОС. Анализ показывает, что это возможно только при ис-пользовании платформы виртуализации VMware, при ус-ловии, что в гостевой ОС установлены средства интегра-ции – VMware Tools. Данный способ действительно прост и удобен, не предполагает каких-либо трудностей при реа-лизации, и пример действий будет приведен в конце статьи для сравнения. Однако по причине указанных выше ограни-чений – имеющаяся платформа виртуализации VMware и на-личие установленных VMware Tools – часто мы вынуждены прибегать к другому способу.nnВторой способ носит более изощренный характер и за-ключается в монтировании виртуального диска ВМ в среде ОС хоста, модификации скриптов инициализации и запус-ке виртуальной машины с выполнением подготовленных скриптов. Детальный список действий и используемые средства будут определяться типом платформы виртуа-лизации и типом гостевой ОС, общими будут следующие шаги.nn>    Монтирование виртуального диска ВМ. Средства хоста должны позволять выполнение такой операции, должны присутствовать необходимые драйверы и утили-ты. Также на этом этапе определяется местоположение скриптов инициализации, поскольку виртуальный диск может содержать более одного раздела, и заранее неиз-вестно, какой именно раздел является системным.nn>    Модификация скриптов инициализации. Для реализа-ции этого этапа необходима поддержка файловой сис-темы дисков гостевой ОС в среде хоста виртуализации. Модифицированный скрипт должен обеспечить одно-кратность выполнения кода и остановку гостевой ОС после выполнения скрипта. Этап завершается размонти-рованием виртуального диска. nn>    Старт ВМ с выполнением подготовленных скриптов. nn Результатом этого этапа будет неактивная ВМ, парамет-ры гостевой ОС которой изменены согласно намеченно-му плану.nn >    Опциональный этап – создание снимка ВМ в случае не-обходимости.nnПроверка на практике. Подготовительный этапnnДалее в качестве конкретного примера рассмотрим автоматизацию импорта и модификацию параметров сетевого адаптера одного из оценочных образов ОС Windows, предоставляемых фирмой Microsoft.nnДля тестов удобно выбрать образ минимального объема – Windows Server 2008 R2 Enterprise Edition x64 (Базовая версия). В качестве платформы виртуализации выберем Windows Server 2008 R2, поскольку это позволит наиболее полно проиллюстрировать все возникающие задачи и их ре-шения.nnДля выбранного образа и платформы виртуализации логично использовать Windows PowerShell в качестве языка сценариев. К сожалению, в Windows PowerShell из состава Windows Server 2008 R2 отсутствуют командлеты управления виртуальной средой, поэтому воспользуемся сторон-ним свободно распространяемым решением – модулем pshyperv, доступным на сайте CodePlex. Загруженный модуль необходимо установить в соответствии с прилагае-мыми инструкциями.nnДля удобства представления тестовый скрипт разчленен на отдельные части в соответствии с описанными ранее этапами.nnПервый фрагмент (см. листинг 1) выполняет импорт ВМ и монтирование виртуального жесткого диска. Для им-порта и монтирования используются командлеты модуля pshyperv, поэтому в начале скрипта предусмотрена про-верка установки данного модуля, а также проверка наличия и корректности аргументов скрипта. В качестве аргумента необходимо предоставить путь к папке с файлами ВМ. По-скольку заранее неизвестно, на каком из разделов вирту-ального жесткого диска расположен системный диск ОС, в скрипте выполняется поиск системного раздела среди вновь смонтированных томов по критерию максимального объема. В реальных условиях, возможно, понадобится ис-пользовать более значимые критерии, например, имя тома, либо наличие определенных элементов (например, каталога %systemroot%) в файловой структуре. Завершается данный фрагмент присвоением переменной значения, соответству-ющего системному диску гостевой ОС. Дополнительные пояснения представлены в комментариях в листинге скрипта.n

Листинг 1n# Проверка аргументаnif (-not ($args) -or ($args).count -gt 1) {nWrite-host "Usage: AutoDeploy.ps1 ↵n<drive:\virtualmachinefolder> "nWrite-host " where 'virtualmachinefolder' ↵n- folder with virtulal machine files config.xml."nExitn}n# Проверка установки модуля pshypervnif (-not(Get-Module hyperv)) {import-module hyperv}nif (-not(Get-Module hyperv)) {nWrite-Host "Install module 'HyperV'"nExit}n#Проверка корректности аргумента – наличие каталогаn$vmPath = $args[0]nif (Test-Path $vmPath){n$VMFolder = Get-Item -Path $vmPath\n}nelsen{nWrite-Host "Virtual Machine Folder not found"nExitn}nif(-not ($VMFolder.PSisContainer))n{nWrite-Host "Virtual Machine's item is not folder."nExitn}n$savedir=$pwdn#Импорт ВМnWrite-Host "Import VM in folder " $VMFolder.FullNamen$Exists = Get-VM -name ([string] $VMFolder.Name) ↵n-ErrorAction SilentlyContinuenIf (!($Exists)){nWrite-Host ("Importing virtual machine : ") -noNewLinenWrite-Host ([string] $VMFolder.Name) -foreground GreennWrite-Host Virtual Machine path: ↵n([string] $VMFolder.FullName)nImport-VM -path ([string] $VMFolder.FullName) -WaitnWrite-Hostn} Else {nWrite-Host ('Virtual machine "') -noNewLinenWrite-Host ([string] $VMFolder.Name) -noNewLine ↵n-foreground YellownWrite-Host ('" does already exist.')n}n#Создание виртуального сетевого коммутатора и подключениеn#к нему виртуального сетевого адаптераn$tswitch = Get-VMSwitch -VirtualSwitchName "testswitch"nif (-not $tswitch) {n$tswitch = New-VMPrivateSwitch -VirtualSwitchName ↵n"TestSwitch" | Out-Nulln}nGet-VM -name ([string] $VMFolder.Name) | Get-VMNIC | ↵nSet-VMNICSwitch -VirtualSwitch $tswitch.elementnamen#Получение файлов виртуальных дисков в каталогеn$VHDs = get-childitem "$VMFolder\virtual hard disks\*.vhd"nforeach ($VHD in $VHDs) {nif ($vhd -and ($vhd.length -ne 0)) {nWrite-Host "Mounting for modification VHD " ↵n$VHD.FullNamen#Монтирование виртуального диска и поискn#системного разделаn$volbefore = gwmi -Namespace root\cimv2 ↵n-Class win32_volumenMount-VHD -VHDPaths $VHD.FullName | Out-Nulln$volafter = gwmi -Namespace root\cimv2 ↵n-Class win32_volumen# Поиск системного тома (критерий – максимальныйn# размер, вновь подключенный диск)n$volsel = $nullnforeach ($vol in $volafter) {n$cont = $falsenforeach ($volb in $volbefore) {nif ($volb.deviceid -eq $vol.deviceid){n$cont = $truenn}n}nif (-not ($cont)) {nif ($volsel) {nif ($vol.capacity -gt $volsel.capacity) {n$volsel = $voln}n}nelsen{n$volsel = $voln}n}n}n$sysdrive=$volsel.driveletter

 nnПроверка на практике. Основные действияnnВ следующем фрагменте (см. листинг 2) выполняется модификация стартовых скриптов, которые при запуске ВМ про-изведут необходимые изменения.nnВ       качестве скриптов инициализации выбраны стартап-скрипты групповых политик Windows. Это возможно для серверных ОС Windows, а также для профессиональных  и   корпоративных редакций клиентских Windows. Для других редакций клиентских систем Windows также возможна ор-ганизация стартап-скриптов, сделать это можно путем нас-тройки автоматической регистрации пользователя и моди-фикации логин-скрипта для этого пользователя. Реализация этого варианта выполняется без особого труда на основе представленных листингов.nnПредлагаемый вариант имеет некоторые особенности, связанные с тем, что при монтировании диска отсутствует активная среда гостевой ОС, поэтому нет возможности кон-фигурировать стартовые скрипты штатными средствами. Проведенный анализ позволил сделать вывод, что редакти-рование стартовых скриптов групповых политик и задание связанных с ними конфигурационных параметров возможно выполнить путем прямого редактирования файлов в файло-вой системе виртуального диска и редактирования ключей реестра гостевой ОС.nnВ    представленном фрагменте для организации стартовых скриптов в первую очередь создается структура папок в файловой системе системного диска, затем создаются необходимые конфигурационные файлы. После этого соз-дается стартовый скрипт групповой политики, в котором собственно и предусмотрено выполнение команд модифи-кации параметров активного сетевого адаптера.nnДалее для того, чтобы данная процедура выполнилась только один раз, создается скрипт выключения, в котором стартовый скрипт удаляется из конфигурационных файлов. Кроме этого, необходимо модифицировать ключи реестра гостевой ОС для задействования клиентских расширений (CSE) групповых политик, обеспечивающих выполнение стартовых скриптов.nnЗавершается фрагмент размонтированием виртуально-го жесткого диска.n

Листинг 2.nif ($sysdrive) {nWrite-Host "Drive letter for SysDrive is " $sysdrivenWrite-Host "This volume on the one of partitions ↵nof VHD " $VHD.FullNamenif (Test-Path $sysdrive\windows\system32) {n#Создание структуры папок для стартовых скриптовn#и конфигурационных файловnnew-item $sysdrive\windows\system32\grouppolicy ↵n-itemtype directory -ErrorAction ↵nSilentlyContinue | Out-Nullnnew-item $sysdrive\windows\system32\grouppolicy\ ↵nmachine -itemtype directory -ErrorAction ↵nSilentlyContinue | Out-Nullnnew-item $sysdrive\windows\system32\grouppolicy\ ↵nuser -itemtype directory -ErrorAction ↵nSilentlyContinue | Out-Nullnnew-item $sysdrive\windows\system32\grouppolicy\ ↵nmachine\scripts -itemtype directory↵n-ErrorAction SilentlyContinue | Out-Nullnnew-item $sysdrive\windows\system32\grouppolicy\ ↵nmachine\scripts\startup –itemtype ↵ndirectory -ErrorAction SilentlyContinue ↵n| Out-Nullnnew-item $sysdrive\windows\system32\grouppolicy\ ↵nmachine\scripts\shutdown -itemtype ↵ndirectory -ErrorAction SilentlyContinue | ↵nOut-Nulln#Создание конфигурационных файлов групповых политикn$StrGptIni = '[General]' + "`r`n" + ↵n'gPCMachineExtensionNames=[ ↵n{42B5FAAE-6536-11D2-AE5A-0000F87571E3} ↵n{40B6664F-4972-11D1-A7CA-0000F87571E3}]' ↵n+ "`r`n" + 'Version=5'nout-file -filepath "$sysdrive\windows\system32\ ↵ngrouppolicy\gpt.ini" -InputObject ↵n$StrGptIni -encoding ascii | Out-Nulln$StrScriptsIni= "`r`n" + '[Startup]' + "`r`n" + ↵n'0CmdLine=c:\windows\system32\ ↵ngrouppolicy\machine\scripts\startup\ ↵nstartup.cmd' + "`r`n" + '0Parameters=' ↵n+ "`r`n" + '[Shutdown]' + "`r`n" + ↵n'0CmdLine=c:\windows\system32\ ↵ngrouppolicy\machine\scripts\shutdown\ ↵nremove.cmd' + "`r`n" + '0Parameters='nout-file -filepath "$sysdrive\windows\system32\ ↵ngrouppolicy\machine\scripts\scripts.ini" ↵n-inputobject $StrScriptsIni -encoding ↵nascii | Out-Nulln#Создание стартового скриптаn$StrStartupCmd = 'For /f "skip=3 tokens=4*" ↵n%%a In (' + "'NetSh Interface IPv4 Show ↵nInterfaces'" + ') Do (Call ↵n:UseNetworkAdapter %%a "%%b") ' + "`r`n" ↵n+ 'c:\windows\system32\shutdown.exe -f ↵n-s -t 30' + "`r`n" + 'Exit /B' + "`r`n" ↵n+ ':UseNetworkAdapter' + "`r`n" + 'If ↵n%1==connected (@if %2 neq "Loopback ↵nPseudo-Interface 1" ( netsh int ipv4 ↵nset addr %2 static 10.10.0.33 ↵n255.255.0.0 10.10.0.1))' + "`r`n" + ↵n'Exit /B' + "`r`n"nout-file –filepath "$sysdrive\windows\system32\ ↵ngrouppolicy\machine\scripts\startup\ ↵nstartup.cmd" -InputObject ↵n$StrStartupCmd -encoding ascii | Out-Nulln#Создание скрипта выключения гостевой ОСn$StrRemoveCmd = 'del /q c:\windows\system32\ ↵ngrouppolicy\machine\scripts\startup\ ↵nstartup.cmd' + "`r`n" + 'del /q ↵nc:\windows\system32\grouppolicy\machine\ ↵nscripts\scripts.ini' + "`r`n" + 'del /q ↵nc:\windows\system32\grouppolicy\gpt.ini' ↵n+ "`r`n" + 'c:\windows\system32\reg.exe ↵ndelete "HKLM\software\microsoft\windows\ ↵ncurrentversion\group policy\Status\ ↵nGPExtensions\{42B5FAAE-6536-11D2-AE5A- ↵n0000F87571E3}" /f '+ "`r`n" + 'del /q ↵nc:\windows\system32\grouppolicy\machine\ ↵nscripts\shutdown\remove.cmd'nout-file -filepath "$sysdrive\windows\system32\ ↵ngrouppolicy\machine\scripts\shutdown\ ↵nremove.cmd" -InputObject $StrRemoveCmd ↵n-encoding ascii | Out-Nullnn#Модификация ключей реестра для задействования CSEncd C:\Windows\System32nC:\Windows\System32\reg.exe load HKLM\onvhd ↵n$sysdrive\Windows\System32\config\ ↵nSOFTWARE | out-nullnreg add "HKLM\onvhd\microsoft\windows\ ↵ncurrentversion\group policy\Status\↵nGPExtensions\{42B5FAAE-6536-11D2-AE5A-↵n0000F87571E3}" /f | out-nullnreg add "HKLM\onvhd\microsoft\windows\ ↵ncurrentversion\group policy\Status\↵nGPExtensions\{42B5FAAE-6536-11D2-AE5A- ↵n0000F87571E3}" /v ForceRefreshFG ↵n/t REG_DWORD /d 0 /f | out-nullnreg add "HKLM\onvhd\microsoft\windows\ ↵ncurrentversion\group policy\Status\ ↵nGPExtensions\{42B5FAAE-6536-11D2-AE5A-↵n0000F87571E3}" /v LastPolicyTime ↵n/t REG_DWORD /d 0 /f | out-nullnreg add "HKLM\onvhd\microsoft\windows\ ↵ncurrentversion\group policy\Status\ ↵nGPExtensions\{42B5FAAE-6536-11D2-AE5A-↵n0000F87571E3}" /v PrevRsopLogging ↵n/t REG_DWORD /d 0 /f | out-nullnreg add "HKLM\onvhd\microsoft\windows\ ↵ncurrentversion\group policy\Status\ ↵nGPExtensions\{42B5FAAE-6536-11D2-AE5A-↵n0000F87571E3}" /v PrevSlowLink ↵n/t REG_DWORD /d 0 /f | out-nullnreg add "HKLM\onvhd\microsoft\windows\ ↵ncurrentversion\group policy\Status\ ↵nGPExtensions\{42B5FAAE-6536-11D2-AE5A-↵n0000F87571E3}" /v RsopStatus ↵n/t REG_DWORD /d 0 /f | out-nullnreg add "HKLM\onvhd\microsoft\windows\ ↵ncurrentversion\group policy\Status\ ↵nGPExtensions\{42B5FAAE-6536-11D2-AE5A-↵n0000F87571E3}" /v Status /t REG_DWORD ↵n/d 0 /f | out-nullnreg unload HKLM\onvhd | out-nulln}n}nelsen{nWrite-Host "Drive letter not assigned for " $VHD.FullNamen}nDismount-VHD -VHDPaths $VHD.FullName -Forcen}n}ncd $saveDir

 nnПроверка на практике. ИсполнениеnnНаконец остается запустить ВМ, дождаться завершения ее работы и создать снимок ВМ. Эти действия выполняет оставшийся фрагмент скрипта (см. листинг 3).n

Листинг 3.n#Запуск ВМn$Exists = get-vm -name ([string] $VMFolder.Name) ↵n-ErrorAction SilentlyContinuenIf ($Exists){nWrite-Host ("Starting virtual machine : ") -noNewLinenWrite-Host ([string] $VMFolder.Name) -foreground Greenn$exists | start-vm -waitn#Ожидание завершения работы ВМ с проверкой 6-минутногоn#тайм-аутаn$checktime = (get-date).addminutes(6)nwhile ((($exists | Get-VMState).enabledstate ↵n-eq "running") ↵n-and ((get-date).compareto($checktime) -lt 0)){nstart-sleep 5n}n#Если ВМ еще работает, запускается принудительноеn#выключениеnnif (($exists | Get-VMState).enabledstate -eq "running") {nWrite-Host "Forced shutdown VM " $exist.elementnamen$exists | Invoke-VMShutdown ↵n-force -ShutdownTimeOut 2n}nwhile (-not (($exists | Get-VMState).enabledstate ↵n-eq "stopped")){nstart-sleep 1n}nif (($exists | Get-VMState).enabledstate -eq "stopped") {n# Создание снимка виртуальной машиныnWrite-Host "Create snapshot for virtual machine " ↵n$exists.elementnamen$exists | New-VMSnapshot -Wait -Force -Note ↵n"StartImage" | Out-Nulln}nWrite-Hostn}nElsen{nWrite-Host ('Virtual machine "') -noNewLinenWrite-Host ([string] $DriveDstFolder.Name) ↵n-noNewLine -foreground magentanWrite-Host ('" does not exist. Skip.')n}

Для выполнения скрипта необходимо распаковать ВМ в выбранную папку и запустить скрипт с аргументом, указывающим на путь к этой папке. Результатом выполнения скрипта будет подготовленная ВМ в выключенном состо-янии, с модифицированными параметрами гостевой ОС и снимком состояния.nnТо же самое штатными средствамиnnДля сравнения приведу пример управления гостевой ОС штатными средствами хоста виртуализации, что возможно в среде VMware при установленных средствах интеграции VMware Tools и использовании в качестве клиента vSphere PowerCLI . При таких условиях часть скрипта, выполняю-щего модификацию параметров гостевой ОС виртуальной машины VMname будет представлена строками листинга 4.n

Листинг 4.n#Подготовка содержимого командного файлаn$StrCmd = 'For /f "skip=3 tokens=4*" %%a In ↵n(' + "'NetSh Interface IPv4 Show Interfaces'" ↵n+ ') Do (Call :UseNetworkAdapter %%a "%%b") ' + ↵n"`r`n" + 'c:\windows\system32\shutdown.exe -f -s ↵n-t 30' + "`r`n" + 'Exit /B' + "`r`n" + ↵n':UseNetworkAdapter' + "`r`n" + 'If %1==connected ↵n(@if %2 neq "Loopback Pseudo-Interface 1" ↵n( netsh int ipv4 set addr %2 static 10.10.0.33 ↵n255.255.0.0 10.10.0.1))' + "`r`n" + 'Exit /B' + ↵n"`r`n"n# Сохранение файла в файловой системе хоста виртуализацииnout-file –filepath "c:\changeip.cmd" -InputObject $StrCmd ↵n-encoding ascii | Out-Nulln#Копирование файла в гостевую операционную системуnCopy-VMGuestFile -Source c:\changeip.cmd -Destination ↵nc:\temp\ -VM "VMname" -LocalToGuest -GuestUser ↵nAdministrator -GuestPassword Pa$$w0rdn#Выполнение подготовленного командного файлаnGet-VM "VMname" | Invoke-VMscript -ScriptText ↵n"c:\temp\changeip.cmd" -ScriptType Bat -GuestUser ↵nAdministrator -GuestPassword Pa$$w0rd

В этом случае нет нужды манипулировать стартовыми скриптами, поскольку команды установки параметров выполняются непосредственно в среде гостевой ОС, при работающей ВМ. Разумеется, что в таком варианте может потребоваться перезагрузка гостевой ОС, если этого требуют выполненные изменения.nnДополнительно отмечу, что, если в качестве гостевой ОС используется Windows Server 2012 R2, скрипт примет еще более простой вид, представленный на листинге 5. (Подраз-умевается, что в гостевой ОС имеется только один активный сетевой адаптер.)n

Листинг 5.nGet-VM "VMname" | Invoke-VMscript -ScriptText 'New-NetIPAddress -InterfaceIndex ((Get-NetAdapter).ifindex) -IPAddress 10.10.0.33 -PrefixLength 16’ -GuestUser Administrator -GuestPassword Pa$$w0rd

 nnМожно предположить, что в очередных версиях платформы виртуализации Hyper-V будет реализован аналогичный спо-соб управления. Об этом говорит то, что роль виртуализации ОС Windows Server 2012 R2 поддерживает копирование файлов в гостевую ОС (но не из гостевой ОС на хост виртуализации) с помощью командлета Copy-VMFile.nnЕсли клиентское ПО продолжит развитие в этом направлении и будет реализовано не только копирование файлов, но и выполнение произвольных команд, описанные в дан-ной статье манипуляции потеряют актуальность в контексте платформ виртуализации. В настоящее же время описанный способ управления может послужить примером для реализации различных сценариев автоматизации виртуальной инфраструктуры.nnИсточник «Системный администратор» №156, 2015n

Сопровождение систем виртуализации, установка и настройка, [email protected]