Archives for posts with tag: PowerCLI

One of the last projects I’ve been involved with at Seatrans, is to auto­mate the instal­la­tion and con­fig­u­ra­tion of vSphere ESXi 5 hosts for deploy­ment on ves­sels. I’ve talked a bit about this before, both on vSoup and in Set­ting Up Auto­mated ESXi Deploy­ments where I out­lined my PXE and Pow­er­CLI based instal­la­tion and con­fig­u­ra­tion scheme. Not much has changed since then, except updat­ing the PXE server to offer ESXi 5, instead of ESXi 4 and a lot of work has been put into the script­ing, includ­ing a front-end GUI for the Pow­er­CLI script itself. The end “prod­uct” is now in place for mass deploy­ments for inter­nal use.

The fol­low­ing video shows how the PXE based instal­la­tion works, as well as a run through the now GUI based con­fig­u­ra­tion tool aptly called Seatrans Hyper­vi­sor Instal­la­tion Tool.

The video jumps a bit between two VMs, one run­ning Win­dows Server 2008 R2, that runs the DHCP/PXE ser­vices and the Pow­er­CLI script, and one that gets ESXi installed and configured:

This goes to show that you can cre­ate your own, spe­cial­ized and portable deploy­ment solu­tion with­out requir­ing elab­o­rate net­work con­fig­u­ra­tions or recon­fig­ur­ing of exist­ing infrastructure.

Note: I will not be pro­vid­ing down­load­able ver­sions of the final script at this time. The rea­son for this is quite sim­ple, it’s very spe­cific and tai­lored for a non-generic envi­ron­ment. If I can man­age to find the time, I’ll post a generic ver­sion later but in order for any­one else to uti­lize the Pow­er­CLI scripts I’ve cre­ated, a lot of work is required.

Automat­ing ESXi installs was made much eas­ier after the release of vSphere 4.1 where the Scripted Install fea­ture was added, and by using VMware Auto Deploy from VMware Labs. VMware Auto Deploy requires that you have vCen­ter and Host Pro­files in your envi­ron­ment, and that again requires that you have Enter­prise Plus licenses in your environment.

It is, how­ever, pos­si­ble to deploy ESXi in an auto­mated fash­ion com­pletely with­out vCen­ter and Host Pro­files! By using a com­bi­na­tion of a PXE based instal­la­tion and Pow­er­CLI for automat­ing the setup of ESXi after the ini­tial deploy­ment. As this setup has been put together for a spe­cific work project, my Pow­er­CLI script also copies a VM tem­plate to the deployed ESXi host as well as the vMA for admin­is­tra­tive tasks. There is one caveat with regards to this setup though, and that is that the free ver­sion of ESXi only allows Pow­er­CLI in read-only mode. This means that you will either need to get licenses for the ESXi install, or use trial licenses. With the price drop from VMware on the Remote Office / Branch Office (ROBO) licenses, we’re look­ing at using that licens­ing model for our fleet of vessels.

Overview

The “com­plete pack­age” con­sists of the fol­low­ing components:

  • Deploy­ment VM
    This is a cus­tom VM, built to pro­vide DHCP and PXE ser­vices to do the actual ESXi installation
  • Pow­er­shell + Pow­er­CLI
    Scripts that con­fig­ure the ESXi host, post instal­la­tion, and copy your ini­tial VMs to the new host

Our cur­rent process looks like this:

  1. Con­nect phys­i­cal host to deploy­ment lap­top via ethernet
  2. Start deploy­ment VM on deploy­ment laptop
  3. When deploy­ment VM is fin­ished boot­ing, start phys­i­cal host
  4. Phys­i­cal host boots of net­work and PXE and installs ESXi
  5. When ESXi instal­la­tion fin­ishes, run Pow­er­CLI script against host
  6. Dis­con­nect deploy­ment lap­top and phys­i­cal host, and con­nect phys­i­cal host to ves­sel network
  7. Con­nect vSphere Client to ESXi install and start server VM

Deploy­ment VM

Since our deploy­ment sce­nario might be a bit out of the ordi­nary, we have the deploy­ment VM set up on VMware Work­sta­tion or VMware Player on a lap­top. The rea­son for this is that we need a mobile deploy­ment model as the loca­tions we are deploy­ing this on are not sta­tic. Not only are they mobile, they are actu­ally float­ing around on rather large oceans. That’s right, we’re deploy­ing ESXi hosts on our ves­sels world wide!

Basic VM Setup

The basic setup is a stan­dard Win­dows Server 2008 R2 with IIS installed. We will not be using any of the DHCP or other net­work­ing fea­tures included in Server 2008. In our envi­ron­ment it’s con­fig­ured with a sta­tic ip of 172.16.200.1

DHCP + PXE Setup

For DHCP and PXE ser­vices, we are using Tftpd32 a free and open source appli­ca­tion that pro­vides us with all the required ser­vices for deploy­ment eg. both DHCP and PXE.

Kick­start Script

Our very basic kick­start script — ks.cfg — looks like this

vmac­cep­teula
rootpw pass­word
autopart first­disk over­writevmfs
install url http://172.16.200.1/ESXi
net­work boot­proto=dhcp device=vmnic0
reboot

Basi­cally this sets the root pass­word, auto­mat­i­cally deletes all par­ti­tions and sets up a new vmfs, tells the installer that it will find the instal­la­tion files via http on the server and sets the net­work­ing con­fig­u­ra­tion to DHCP. This will of course need tweak­ing in your envi­ron­ment, but this should at least get you started with build­ing your own. More details on the ks.cfg boot­strap com­mands can be found in the ESX and vCen­ter Server Instal­la­tion Guide

Pow­er­CLI Con­fig­u­ra­tion Script

########################################################
#
# Cre­ated by Chris­t­ian Mohn
# for Seatrans AS
#
# No war­ranty sug­gested or implied
#
########################################################</code>

#con­nect to Vir­tu­al­Cen­ter or ESX host
#
func­tion Reg­is­ter-VMX {
param($enti­ty­Name = $null,$dsNames = $null,$tem­plate = $false,$ignore = $null,$check­NFS = $false,$whatif=$false)

func­tion Get-Usage{
Write-Host “Para­me­ters incor­rect” –Fore­ground­Color red
Write-Host “Register-VMX –enti­ty­Name –dsNames [,…]“
Write-Host “enti­ty­Name : a cluster-, dat­a­cen­ter or ESX host­name (not together with –dsNames)“
Write-Host “dsNames : one or more data­s­tore­name names (not together with –enti­ty­Name)“
Write-Host “ignore : names of fold­ers that shouldn’t be checked“
Write-Host “tem­plate : reg­is­ter guests ($false)or tem­plates ($true) — default : $false“
Write-Host “check­NFS : include NFS data­s­tores — default : $false“
Write-Host “whatif : when $true will only list and not exe­cute — default : $false“
}

if(($enti­ty­Name –ne $null –and $dsNames –ne $null) –or ($enti­ty­Name –eq $null –and $dsNames –eq $null)){
Get-Usage
break
}

if($dsNames –eq $null){
switch((Get-Inven­tory –Name $enti­ty­Name).Get­Type().Name.Replace(“Wrap­per”,””)){
“Clus­ter”{
$dsNames = Get-Clus­ter –Name $enti­ty­Name | Get-VMHost | Get-Data­s­tore | where {$_.Type –eq VMFS –or $check­NFS} | % {$_.Name}
}
“Dat­a­cen­ter”{
$dsNames = Get-Dat­a­cen­ter –Name $enti­ty­Name | Get-Data­s­tore | where {$_.Type –eq VMFS –or $check­NFS} | % {$_.Name}
}
“VMHost”{
$dsNames = Get-VMHost –Name $enti­ty­Name | Get-Data­s­tore | where {$_.Type –eq VMFS –or $check­NFS} | % {$_.Name}
}
Default{
Get-Usage
exit
}
}
}
else{
$dsNames = Get-Data­s­tore –Name $dsNames | where {$_.Type –eq VMFS –or $check­NFS} | Select –Unique | % {$_.Name}
}

$dsNames = $dsNames | Sort-Object
$pat­tern = “*.vmx“
if($tem­plate){
$pat­tern = “*.vmtx“
}

fore­ach($dsName in $dsNames){
Write-Host “Check­ing ” –NoNew­line; Write-Host –Fore­ground­Color red –Back­ground­Color yel­low $dsName
$ds = Get-Data­s­tore $dsName | Select –Unique | Get-View
$dsBrowser = Get-View $ds.Browser
$dc = Get-View $ds.Par­ent
while($dc.MoRef.Type –ne “Dat­a­cen­ter”){
$dc = Get-View $dc.Par­ent
}
$tgt­folder = Get-View $dc.VmFolder
$esx = Get-View $ds.Host[0].Key
$pool = Get-View (Get-View $esx.Par­ent).Resour­ce­Pool

$vms = @()
fore­ach($vmImpl in $ds.Vm){
$vm = Get-View $vmImpl
$vms += $vm.Config.Files.VmPathName
}
$data­s­torepath = “[“ + $ds.Name + ”]“

$search­spec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec
$search­spec.Match­Pat­tern = $pat­tern

$taskMoRef = $dsBrowser.SearchDatastoreSubFolders_Task($data­s­torePath, $search­Spec)

$task = Get-View $taskMoRef
while (“run­ning”,“queued” –con­tains $task.Info.State){
$task.Updat­e­View­Data(“Info.State”)
}
$task.Updat­e­View­Data(“Info.Result”)
fore­ach ($folder in $task.Info.Result){
if(!($ignore –and (&{$res = $false; $folder.FolderPath.Split(”]”)[1].Trim(” /”).Split(”/”) | %{$res = $res –or ($ignore –con­tains $_)}; $res}))){
$found = $FALSE
if($folder.file –ne $null){
fore­ach($vmx in $vms){
if(($folder.Fold­er­Path + $folder.File[0].Path) –eq $vmx){
$found = $TRUE
}
}
if (–not $found){
if($folder.Fold­er­Path[-1] –ne “/”){$folder.Fold­er­Path += “/”}
$vmx = $folder.Fold­er­Path + $folder.File[0].Path
if($tem­plate){
$params = @($vmx,$null,$true,$null,$esx.MoRef)
}
else{
$params = @($vmx,$null,$false,$pool.MoRef,$null)
}
if(!$whatif){
$taskMoRef = $tgt­folder.Get­Type().Get­Method(“RegisterVM_Task”).Invoke($tgt­folder, $params)
Write-Host ‘t $vmx “reg­is­tered“
}
else{
Write-Host ‘t $vmx “reg­is­tered” –NoNew­line; Write-Host –Fore­ground­Color blue –Back­ground­Color white ” ==> What If“
}
}
}
}
}
Write-Host “Done“
}
}

# Register-VMX –enti­ty­Name “MyDat­a­cen­ter“
# Register-VMX –dsNames “datastore1”,“datastore2“
# Register-VMX –dsNames “datastore1”,“datastore2” –template:$true
# Register-VMX –enti­ty­Name “MyDat­a­cen­ter” –ignore “Some­Folder“
# Register-VMX –dsNames “datastore3”,“datastore4” –ignore “Some­Folder” –checkNFS:$true
# Register-VMX –enti­ty­Name “MyDat­a­cen­ter” –whatif:$true

if ($args[0] –eq $null)
#
{$host­Name = Read-Host “Enter ESX Host Name or IP}
#
else
#
{$host­Name = $args[0]}
#
#
#con­nect to selected Vir­tu­al­cen­ter or host server
#
Con­nect-VIS­erver $host­Name

# Set Data­s­tore Name
$dsName = “datastore1“
$ds = Get-Data­s­tore –Name $dsName
New-PSDrive –Name $dsName –Root \ –PSProvider Vim­Data­s­tore -Data­s­tore $ds

# Copy and Reg­is­ter VM from local drive to ESXi Host
Copy-Data­s­tor­e­Item C:\VMs\MyTestVM\* datastore1:\MyTestVM\ –Force
Reg­is­ter-VMX -dsNames $dsName

# Import vMA ovf
Import-VApp -Source c:\VMs\vMA\vMA-4.1.0.0-268837.ovf -VMHost $host­Name -Data­s­tore $ds

# Lets con­fig­ure the host

########################################################
# Host Con­fig­u­ra­tion #
########################################################

#Dis­able IPv6
Get-VMHost­Net­workAdapter | where { $_.Port­Group­Name –eq “Ser­vice Con­sole 1″ } | Set-VMHost­Net­workAdapter -IPv6Enabled $false

# Con­fig­ure net­work­ing
# Not fin­ished

# Con­fig­ure NTP Server
Add-VMHost­NtpServer -VMHost $host­Name -NtpServer “0.vmware.pool.ntp.org“
Add-VMHost­NtpServer -VMHost $host­Name -NtpServer “1.vmware.pool.ntp.org“
Add-VMHost­NtpServer -VMHost $host­Name -NtpServer “2.vmware.pool.ntp.org“

# Set VM Start Pol­icy
$vmstart­pol­icy = Get-VMStart­Pol­icy -VM MyTestVM
Set-VMStart­Pol­icy -Start­Pol­icy $vmstart­pol­icy -Star­tAc­tion PowerOn

This Pow­er­CLI script is not 100% fin­ished yet, the net­work­ing part remains to be auto­mated to pro­vide cor­rect con­fig­u­ra­tion based on which ves­sel we are deploy­ing to, but in gen­eral it’s pretty much good to go.

Of course, there are loads of ways to extend and improve this process, but for now this suits our needs very well. I’m sure I’ll need to revise it once vSphere.next is out and ready for deployment.

Using a model like this, com­bined with some inter­est­ing usage pat­terns for vMA you can cre­ate an auto­mated ESXi deploy­ment sce­nario that let’s you deploy, patch and man­age your remote vSphere infra­struc­ture in a pretty stream­lined fashion.


A cou­ple of days ago, while I was at VMworld Europe I got the fol­low­ing tweet from Asb­jørn A. Mikkelsen (@neslekkim) (trans­lated from norwegian):

@h0bbel Do you know if I can script some­thing against vCen­ter to dupli­cate (or cre­ate from tem­plate) VMs, and also start/stop them?

My imme­di­ate response, was of course to sug­gest using Pow­er­CLI. Asb­jørn, who works as a full time devel­oper, jumped at Pow­er­CLI imme­di­ately and within a very short time frame came up with a Pow­er­CLI script for the task at hand.

You can down­load the script and play around with it, if you want. Inline doc­u­men­ta­tion is in Nor­we­gian, and if Asb­jørn had intended to redis­trib­ute the script I’m sure he would have opti­mized it more than the cur­rent revi­sion.
Con­tinue read­ing “Devel­oper meets Pow­er­CLI — awe­some­ness ensues” »