I couldn’t find a PowerCLI script to clone Linux and assign ip addresses to multiple adapters so I decided to write my own.
If you are new to Vsphere PowerCLI, you may need to check my previous post to learn how to connect to vi-server via PowerCLI at first.
There are 2 scripts:
discover-info.ps1 # Discovery information of target viserver/ESX host and generate template file to be used for clonevm.ps1
vmclone.ps1 #clone after read information from template file generated by discover-info.ps1 script
The scripts has been tested in VMware vSphere PowerCLI 4.0 for VMs in ESX 3.5/ESX4.0 managed by Virtual Center Server.
Scripts in action
[vSphere PowerCLI] D:\Temp> .\discover-info.ps1Discovered ESX hosts:esx01 esx02Please enter target ESX hostname: esx01..Template file: vmdata.txt has been generated. Edit the file then run 'clonevm.ps1 -f file-name' to start cloning
[vSphere PowerCLI] D:\Temp> cat vmdata.txt (after customization)============####---------------- Discovered information
#PortGroups='Service Console' 'vlan-01' 'vlan-02'
#Folders='host' 'Discovered Virtual Machine' 'Datacenters' 'vm'
#DataStores= 'nfs_storage' 'esx01:storage1'
#resourcepools=Name: Resources ID:ResourcePool-resgroup-7 Name: Resources ID:ResourcePool-resgroup-65
####----------------
####----------------Customize your VM values using the template
esxhost=esx01##Resource pool id is NOT required for using virtual machine as source, but IS required for using template as source
#resourcepoolid=
#vm means Virtual Machine; vt means template ( resourcepoolid is required for vt)
SrcName=vm,linuxtemplateDstName=pstest1##Use vm as folder if no user folders defined
Folder=vmDataStore=nfs_storage##Gateway is optional, enter - to skip this value
##Networkadapter type is optional (Auto choosen for guest OS) , enter - to skip this value
##Supported adapter types: e.g e1000, Flexible, Vmxnet, EnhancedVmxnet
Network=EnhancedVmxnet,vlan-01 ,172.19.1.1,255.255.248.0,172.19.1.10 ; -,vlan-02,172.20.1.1,255.255.255.0,-DNS=10.1.1.1,10.1.1.2Domain=example.com#Poweron=yes
####----------------
[vSphere PowerCLI] D:\Temp> .\clonevm.ps1 -f .\vmdata.txt==> Retrieving info for source VM: linuxtemplate
==> Starting clone process ...4% 10% 16% 21% 27% 33% 38% 45% 51% 57% 62% 68% 74% 79% 85% 91% %Completed Task: Task-task-2366==> Checking new VM ...Name PowerState Num CPUs Memory (MB)---- ---------- -------- -----------pstest1 PoweredOff 1 4096==> Removing existing network adapters ...==> Adding 2 new network adapters .....==> Customizing guest OS ...%Completed Task: Task-task-2370==> Checking new VM ...pstest1 PoweredOff 1 4096
Discover-info.ps1 download
# *Execute the script in a live PowerCLI VIsserver session*
# Generate template file to be used for clonevm.ps1
# DATE: 12 Oct 2010
# Author: http://honglus.blogspot.com
$template_file="vmdata.txt"
$hosts=get-vmhost | foreach { $_.name }write-host "Discovered ESX hosts: $hosts"
switch ($hosts.length) {0 { write-host "no ESX host found! exiting.. " ; exit}1 { $esxhost=$hosts[0] }default {$esxhost=read-host "Please enter target ESX hostname"
if ( -not $($hosts -contains "$esxhost") ) { write-host "Unknown host: '$esxhost', exiting.. " ; exit }}}$pgs=Get-VirtualPortGroup -vmhost $esxhost | foreach { "'$_'" }
$folders=get-folder | foreach { "'$_'" }
$dss=get-datastore -vmhost $esxhost | foreach { "'$_'"}
$rspool=get-resourcepool | foreach { "Name: " + $_.name + " ID:" + $_.id }write-output "
####---------------- Discovered information
#PortGroups=$pgs
#Folders=$folders
#DataStores= $dss
#resourcepools=$rspool
####----------------
####----------------Customize your VM values using the template
esxhost=$esxhost##Resource pool id is NOT required for using virtual machine as source, but IS required for using template as source
#resourcepoolid=
#vm means Virtual Machine; vt means template ( resourcepoolid is required for vt)
SrcName=vm,clone1DstName=guest1##Use vm as folder if no user folders defined
Folder=vmDataStore=data_store##Gateway is optional, enter - to skip this value
##Networkadapter type is optional (Auto choosen for guest OS) , enter - to skip this value
##Supported adapter types: e.g e1000, Flexible, Vmxnet, EnhancedVmxnet
Network=adapter-type,port-group1,ip-address1,net-mask1,gateway1 ; EnhancedVmxnet,port-group2,ip-address2,net-mask2,gateway2 ; ...DNS=dns1,dns2Domain=example.comPoweron=yes####----------------
" | tee $template_file
write-host "Template file: $template_file has been generated. Edit the file then run 'clonevm.ps1 -f file-name' to start cloning"
clonevm.ps1 download
# *Execute the script in a live PowerCLI VIsserver session*
##### Clone VM for Linux guest
#Read information from template file generated by discover-info.ps1 script
#Set target host/datastore for Clone ;Start Clone
#Delete existing adapters; add new adapters; Customize guest OS; powerone VM (Optional)
#DATE: 12 Oct 2010
#Author: http://honglus.blogspot.com
if ( ( $args.count -ne 2 ) -or ( $args[0] -ne "-f" ) ) { write-host "Usage: .\program -f template-filename" ; exit}$file1=$args[1]function Retrieve-Values {$strings=$args[0]$item=$args[1]$line=[string] ($strings | select-string -pattern "$item")$line=$line.trim()return $line.Substring( $line.LastIndexOf("=")+1 )}function wait-for-task {
if ( $args[0] -eq $null ) {write-host "failed " ;exit }$tskid=$args[0]$progress=get-task -status running | foreach { if ( $_.id -eq $tskid ) { $_.PercentComplete } }
while ( $progress -ne $null ) {
sleep 30
$progress=get-task -status running | foreach { if ( $_.id -eq $tskid ) { $_.PercentComplete} }
write-host "$progress% " -nonewline
}write-host ""write-host "Completed Task:" $tskid
}$lines=get-content $file1 -ErrorAction stop | select-string -notmatch "(^#|^$)" -ErrorAction stop$s_esxhost=Retrieve-values $lines "esxhost"
$s_rspoolid=Retrieve-values $lines "resourcepoolid"
$s_srcname=Retrieve-values $lines "SrcName"
$s_dstname=Retrieve-values $lines "Dstname"
$s_folder=Retrieve-values $lines "Folder"
$s_datastore=Retrieve-values $lines "DataStore"
$s_domain=Retrieve-values $lines "Domain"
$s_network=Retrieve-values $lines "Network"
$s_poweron=Retrieve-values $lines "Poweron"
$s_dns=Retrieve-values $lines "DNS"
$s_dns=$s_dns.split(",")$array_temp=$s_network.split(";")$nic_cnt=$array_temp.count#Initialize hash table
$h_network=@{atype=(1..$nic_cnt); pgroup=(1..$nic_cnt); ip=(1..$nic_cnt); mask=(1..$nic_cnt); gateway=(1..$nic_cnt) }For ($i=0; $i -lt $nic_cnt ; $i++) {$array_temp2=$array_temp[$i].split(",")if ( $array_temp2.count -ne 5 ) { write-host "Expected the number of values for network is 5, given" $array_temp2.count ; exit}$h_network.atype[$i]=$array_temp2[0].trim()$h_network.pgroup[$i]=$array_temp2[1].trim()$h_network.ip[$i]=$array_temp2[2].trim()$h_network.mask[$i]=$array_temp2[3].trim()$h_network.gateway[$i]=$array_temp2[4].trim()}$vmclonespec_host = New-Object VMware.Vim.VirtualMachineCloneSpec#### Customize Target host /Target datastore
$vmclonespec_host.location = New-Object VMware.Vim.VirtualMachineRelocateSpec$vmclonespec_host.location.host = (Get-vmHost -Name $s_esxhost | Get-View).MoRef$vmclonespec_host.location.datastore = (Get-Datastore -Name $s_datastore| Get-View).MoRefif ( $s_rspoolid.length -gt 0 ) {$vmclonespec_host.location.pool= (Get-ResourcePool -id $s_rspoolid -ErrorAction stop|get-view).MoRef}#### Customize Guest OS
$vmclonespec_os= New-Object VMware.Vim.CustomizationSpec## Identity for Linux
$vmclonespec_os.identity= New-Object VMware.Vim.CustomizationLinuxPrep$vmclonespec_os.identity.hostname= New-Object VMware.Vim.CustomizationFixedName$vmclonespec_os.identity.hostname.name= $s_dstname$vmclonespec_os.identity.domain=$s_domain#GlobalIPSettings
$vmclonespec_os.GlobalIPSettings = New-Object VMware.Vim.CustomizationGlobalIPSettings$vmclonespec_os.GlobalIPSettings.dnsServerList=$s_dns$vmclonespec_os.GlobalIPSettings.dnsSuffixList=$s_domain# adapter mapping
for ( $i=0; $i -lt $nic_cnt; $i++ ) {
$vmclonespec_os.NicSettingMap += @(New-Object VMware.Vim.CustomizationAdapterMapping)$vmclonespec_os.NicSettingMap[$i].Adapter = New-Object VMware.Vim.CustomizationIPSettings$vmclonespec_os.NicSettingMap[$i].Adapter = New-Object VMware.Vim.CustomizationIPSettings# FixedIP
$vmclonespec_os.NicSettingMap[$i].Adapter.Ip = New-Object VMware.Vim.CustomizationFixedIp$vmclonespec_os.NicSettingMap[$i].Adapter.Ip.IpAddress = $h_network.ip[$i]$vmclonespec_os.NicSettingMap[$i].Adapter.SubnetMask = $h_network.mask[$i]if ( $h_network.gateway[$i] -ne "-" ) {$vmclonespec_os.NicSettingMap[$i].Adapter.Gateway = $h_network.gateway[$i]}}$s_srcname_pre=$s_srcName.substring(0,3)$s_srcname=$s_srcname.Substring( $s_srcname.LastIndexOf(",")+1 )
# Template or Virtual Machine from which the guest will be cloned
write-host "==> Retrieving info for source VM: $s_srcname"
if ( $s_srcname_pre -eq "vm," ) {$svm = Get-View (get-vm $s_srcname -ErrorAction stop ).ID}else {
$svm = Get-View (get-template $s_srcname -ErrorAction stop ).ID}$tfld = Get-Folder -Name $s_folder -ErrorAction stop | Get-Viewwrite-host "==> Starting clone process ... "
$taskid=$svm.CloneVM_Task($tfld.moref,$s_dstname,$vmclonespec_host) | foreach {$_.value}Wait-for-Task "Task-$taskid"write-host "==> Checking new VM ..."
get-vm $s_dstname -ErrorAction stopwrite-host "==> Removing existing network adapters ... "
$adapter = Get-NetworkAdapter -VM "$s_dstname" -ErrorAction stop
if ( $adapter -ne $null ) { Remove-NetworkAdapter -NetworkAdapter $adapter -confirm:$false }write-host "==> Adding " $nic_cnt "new network adapters ... "for ( $i=0; $i -lt $nic_cnt; $i++ ) {
if ( $h_network.atype[$i] -ne "-" ) {New-NetworkAdapter -Type $h_network.atype[$i] -NetworkName $h_network.pgroup[$i] -VM $s_dstname -StartConnected -ErrorAction stop}else {
New-NetworkAdapter -NetworkName $h_network.pgroup[$i] -VM $s_dstname -StartConnected -ErrorAction stop}}write-host "==> Customizing guest OS ... "
$newvm = Get-View (get-vm $s_dstname -ErrorAction stop ).ID$taskid=$newvm.CustomizeVM_Task($vmclonespec_os) | foreach {$_.value}Wait-for-Task "Task-$taskid"write-host "==> Checking new VM ..."
sleep 4
get-vm $s_dstname -ErrorAction stopif ( $S_poweron -eq "yes" ) { start-vm $s_dstname }
Related Documents:
1. vSphere PowerCLI Quick Start
2. Master-PowerShell
3. VMware vSphere Web Services SDK 4.0 (Supported languages: PowerShell C# JAVA Perl )