Автоматическое расширение vmdk и раздела в Guest OS с помощью PowerCLI

В данном топике представлю скрипт по расширению виртуального диска vmdk вместе с расположенным на нем логическим разделом гостевой операционной системы Windows (только Windows!). Данный скрипт писался под платформу vRealize Orchestrator и цель его была возможность с помощью одного тычка в портале Service Broker расширить партицию гостевой OS (а перед этим низлежащего vmdk), которая была полностью забита, к примеру логами базы данных.

Скрипт был упрощен для обычного использования в PowerCLI, безо всяких handler, context и так далее.

Одна из важных его особенностей скрипта и ограничений одновременно – это сопоставление на каком виртуальном диске vmdk расположен интересующий нас раздел. Так как на одном диске vmdk может располагаться несколько разделов гостевой OS или наоборот несколько vmdk могут быть заняты одним разделом, этот скрипт подойдет исключительно для инфраструктур с правилом – один vmdk=один дисковый раздел. Как раз такое правило и существовало у «заказчика». В иных обстоятествах скрипт бесполезен и наоборот может навредить, расширив диск, на котором пара разделов, один из которых нуждается в увеличении пространства, но ввиду свойств таблицы разделов не может быть увеличен. Конечно можно наколдовать с разделами внутри гостевой системы и в результате добиться результата, но речь идет о быстром увеличении по требованию.

Так же скрипт перед тем как расширить определенный vmdk, проверяет наличие доступного свободного места на датасторе, где располагается сам виртуальный диск. И убеждается что после расширения останется минимальный допустимый процент свободного места (его можно подредактировать, если допустим по вашей политике необходимо минимум 20% Free Space на датасторе).

Собственно, сам скрипт.

 #Подключаемся
 Connect-Viserver vcName

 #Эти переменный нужно заполнить!
 #имя машины
 $VMName='vmaNme'
 #логический раздел, который нужно расширить
 $VolumeName="C"
 #сколько гигов накинуть
 $CapacityGBRequired=1
 #Логин учетки Администратора
 $Guest_User='Administrator'
 #Пароль от Администратора
 $Guest_Pass='VMware!23'

 #Смотрим все логические тома в VM
 $VM=Get-Vm $VMName
 Write-Host -ForegroundColor Cyan 'We have these Disks partitions:'
 $VM.ExtensionData.Guest.Disk.DiskPath

 #Узнаем SCSI ID диска внутри гостевой системы
 $VM=Get-VM $VMName
 $Guest_Script1=@'
 [char]$in = "#VolumeName#"
 get-partition -DriveLetter $in | get-disk | Select-Object -ExpandProperty SerialNumber
 '@
 $Guest_Script1=$Guest_Script1.Replace('#VolumeName#',$VolumeName)
 $SCSI_SN_Guest=Invoke-VMScript -VM $VM -GuestUser $Guest_User -GuestPassword $Guest_Pass -ScriptText $Guest_Script1 | select -ExpandProperty ScriptOutput

 #Считаем, хватит ли места и останеться ли оно после расширения
 $VMDK=Get-HardDisk -VM $VM | Where {$_.ExtensionData.Backing.Uuid.Replace('-','').ToLower().Trim() -like $SCSI_SN_Guest.Trim()}
 $VMDK_Current_Size=$VMDK.CapacityGB
 $VMDK_Future_Size=$VMDK_Current_Size+$CapacityGBRequired
 $DatastoreName=$VMDK.ExtensionData.Backing.FileName.Split("[")[1].Split("]")[0]
 $Datastore=Get-Datastore -Name $DatastoreName
 $FutureFreeCapacity=$Datastore.FreeSpaceGB-$CapacityGBRequired
 $FuturePerFree = ([math]::Round(($FutureFreeCapacity)/($Datastore.CapacityGB)*100,2)

 #Если после расширения vmdk места останется на датасторе больше 5%, продолжить.
 if ($FuturePerFree -ge 5)
    {
     Write-Host -ForegroundColor Green 'We will extend vmdk'
     $VMDK | Set-HardDisk -CapacityGB $VMDK_Future_Size -Confirm:$false
    }

 #Если после расширения vmdk места останется на датасторе меньше 5%, прекратить.
 if ($FuturePerFree -le 5)
    {
     Write-Host -ForegroundColor Red 'Not Enough Space'
     Break
    }

 #Расширям логический том внутри гостевой системы
 $Guest_Script2= @'
 Get-Partition -DriveLetter #VolumeName# | %{$size = $_ | Get-PartitionSupportedSize; $_ | Resize-Partition -Size $size.sizeMax}
 '@
 $Guest_Script2=$Guest_Script2.Replace('#VolumeName#',$VolumeName)
 Invoke-VMScript -VM $VM -GuestUser $Guest_User -GuestPassword $Guest_Pass -ScriptText $Guest_Script2

 #Отключаемся
 Disconnect-VIServer vcName -Confirm:$false 

Логика скрипта проста. Сначала определяется SCSI ID диска внутри Guest OS, на котором расположен раздел (Для этого используются VMware Tools и соответственно нужно знать логин и пароль Администратора Guest OS). Затем на основе полученного SCSI ID определяется сам vmdk и Datastore, на котором он расположен в vSphere. Производятся расчеты по возможности расширения, а также учитывается сколько свободного места останется на Datastore после расширения. В моем примере если останется менее 5%, то расширение не произойдем, Вы можете подкорректировать эту величину. Затем скрипт увеличивает объем vmdk в vSphere, лезет опять в Guest OS через VM Tools и расширяет гостевой раздет уже там.