OVA deployment ESXi local datastore

This article is about a script for OVA deployment from ESXi  local datastore. This idea came to my mind after working on one project where I had to deploy OVAs on around 250 ESXi clusters.

Here I used VMware OVFTool and Selenium web-driver. You can Download  both software from the links mentioned below. Import-vAPP command from powercli doesn’t support HTTPS source for OVA deployment from ESXi local data store. You can check its help section for more information.

Import-v App script can be found here OVA Deployment via PowerCLI

OVFTOOL Download

Selenium

Explanation Line by Line-

1 – Path to OVFtool exe.

3-5 –  I have added Selenium binary or DLL using Add-type method.

7 – Path to chrome driver to open ESXi local data store webpage and fetch the HTTPS link

8 -9  – We would need ESXi root credentials here

11- Enter the v Center details

13 – Location of the OVA which needs to be uploaded to local data store

15 – Folder which we will create inside local data store to store OVA

17-30 – Code to upload OVA on local data store of first ESXi inside Cluster

30 -36 – v Switch and port group information to create VMKernel on ESXi hosts.

42-52 – Collecting IP setting for the OVAs

54 – 60 – Collect Names for the OVAs

63 – 68 – Port group and local data store information.

72-83 –  Use of Selenium and Chrome driver to access ESXi local datastore and fetch HTTPS source path

86 – 115 –  Commands to deploy OVA on ESXi hosts with OVFTOOL and VMKernel creation commands.

$ovftool =  "C:\Program Files (x86)\VMware\VMware OVF Tool\ovftool.exe"



Add-Type -Path 'C:\Users\TKMAMIL\Desktop\OVFTOOL\Vipal\selenium-dotnet-3.14.0\dist\WebDriver.dll'
Add-Type -Path 'C:\Users\TKMAMIL\Desktop\OVFTOOL\Vipal\selenium-dotnet-3.14.0\dist\WebDriver.Support.dll'
Add-Type -Path 'C:\Users\TKMAMIL\Desktop\OVFTOOL\Vipal\selenium-dotnet-3.14.0\dist\Selenium.WebDriverBackedSelenium.dll'

$chromedriver =  'C:\Users\vipal\Desktop\user\selenium-dotnet-3.14.0\dist\chromedriver.exe'
$esxpassword = Read-Host -Prompt 'Enter password'

$users = "root"
Connect-VIServer vcenter -User username -Password password

$clusters = Get-Cluster '0673'

$filername = "C:\Users\TKMAMIL\Desktop\RP_for_VMs_5.1.SP1.P5_Installation_Kit_md5_1c01d803b1e6917d3f5e657057955c46\RP_for_VMs_5.1.SP1.P5_Installation_Kit_md5_\EMC_RecoverPoint_vRPA-RP4VMs_rel5.1.SP1.P5_d.246_md5_cf06f6f4b7d0166dc9add0d2926eaccc.ova"

$tgt = 'RP4VM'

foreach ($clus in (Get-Cluster $clusters| sort Name)){

######### Upload OVA to local datastore#######################

$ds = Get-Cluster $clus | Get-VMHost | sort Name | select -First 1 | Get-Datastore | where {$_.name -like "*local*"}

New-PSDrive -Location $ds -Name vg -PSProvider VimDatastore -Root "\" > $null

$position = 0

if(!(Test-Path -Path "vg:/$($tgt)")){

New-Item -ItemType Directory -Path "vg:/$($tgt)" > $null
}

$position ++ 

Write-Progress -Activity "Copying OVA to $ds" -Status "Copying File $filername" -PercentComplete (($position/$filername.count)*100)
 
Copy-DatastoreItem -Item $filername -Destination "vs:/$($tgt)" 

Remove-PSDrive -Name vg -Confirm:$false 
 #################################################################3

 $vswitch = 'vSwitch5'

$pg = 'RP4VM_VMKernel'
$port = 'vRPA_Data'
$subnet = 'subnet'
$subnetprefix = 'x.x.x'
$ipperserver = 1
$firstip = 40
#################################################

#########################################


## collect IP information #########
$IPS = @()
$ucsip = Get-Cluster $clus | Get-VMHost | select -First 1 | Get-VMHostNetwork | select DnsAddress

$split = $ucsip.dnsaddress

$IPbyte = $split[0].Split(".")
$newucsip = ($IPByte[0]+"."+$IPByte[1]+"."+$IPByte[2])

$startip = "103"
$endip = "104"
$gateway = "254"

$netmask = "subnet"

$ucsipaddress = "$newucsip.$($startip+$_)"
$ucsipaddress1 = "$newucsip.$($endip+$_)"
$ucsgateway = "$newucsip.$($gateway+$_)"

$IPS += $ucsipaddress
$IPS += $ucsipaddress1

$internet = 0
#########################################

###########Collect VM name##################

#$VMNAME = @()

#$vm = "Prod$($clus)_vRPA1"
#$vm1 = "Prod$($clus)_vRPA2"

#$VMNAME += $vm
#$VMNAME += $vm1

$i = 1

#################################


########## Select PortGroup #############

$portgoup = get-cluster $clus | Get-VMHost|select -First 1 | Get-VirtualPortGroup |where {$_.name -like "*VMN*"}

###########################
$esx = Get-cluster $clus|Get-VMHost|sort Name | select -First 1

$localdata = $esx | Get-Datastore | where {$_.name -like "*Local*"}

########collect  Source path#######


$options = New-Object -TypeName "OpenQA.Selenium.Chrome.ChromeOptions"
$options.AcceptInsecureCertificates = $true

$driver = New-Object -TypeName "OpenQA.Selenium.Chrome.ChromeDriver($options, $chromedriver)"

$driver.Url = 'https://' + $users + ':' + $esxpassword + '@' + $esx + '/folder'

sleep -Seconds 5

$driver.FindElementByLinkText('ha-datacenter').click()

sleep -Seconds 5

$driver.FindElementByLinkText($localdata).click()

sleep -Seconds 5

#$driver.FindElementByLinkText('iSCSI').click()


$driver.FindElementByLinkText('RP4VM/').click()

sleep -Seconds 5

$source = $driver.FindElementByXPath('/html/body/table[2]/tbody/tr[4]/td[1]/a')

$link = $source.GetAttribute('href')


###################################
    
foreach ($esxhost in (Get-cluster $clus | Get-VMHost | sort Name )){
$virtual = "Prod$($clus)_vRPA" + $i
$datastore = get-cluster $clus | Get-Datastore | where {$_.name -like "$($clus)0" + $i }
$i ++

$protocol = $IPS[$internet]
$internet ++

#$ucsdatastore = $Data[$datastoreloop]
#$datastoreloop ++

Start-Process $ovftool -ArgumentList --X:logFile=ovftool.log, --X:logLevel=trivia,  --acceptAllEulas,--noSSLVerify,--disableVerification,--allowExtraConfig, --poweron, --deploymentOption=Med+, --datastore=$datastore, --network=$portgoup, --prop:ip=$protocol, --prop:netmask=$netmask, --prop:gateway=$ucsgateway, --name=$virtual, $link, vi://tkmamil:abc12DEFghi@vcenter:443/Stores/$clus/host/$clus -NoNewWindow -Wait -RedirectStandardOutput C:\Users\TKMAM\Desktop\output.txt

##### Create Portgroup for vRPA ##############################

Get-VirtualSwitch -VMHost $esxhost -Name $vswitch | New-VirtualPortGroup -Name $port

Get-VirtualSwitch -VMHost $esxhost -Name $vswitch | New-VirtualPortGroup -Name $pg

###############################################################

0..$($ipperserver-1) | %{

$ipaddress = "$subnetprefix.$($firstip + $_)"
$firstip += $ipperserver
New-VMHostNetworkAdapter -VMHost $esxhost -VirtualSwitch $vswitch -IP $ipaddress -SubnetMask $subnet -PortGroup $pg
}
}
$driver.Close()
$driver.Dispose()
$driver.Quit()
}

Hope you liked the OVA deployment from ESXi local datastore script.  Please change the script based on your requirements and share your thoughts.