VMware Cloud Community
elihuj
Enthusiast
Enthusiast
Jump to solution

Clone VM Script

I'm looking to create a PowerCLI script to clone a VM, and overwrite any existing clones that are present. Just doing some searching, here is what I found:

New-VM -Name VM2 -VM VM1 -Datastore datastorename -vmhost hostname

I have not tested the script yet, but it does look like it will do at least part of what I am looking to accomplish. Do I need to use the Datastore and VMhost parameters? And is there anything I can do to delete any existing clones before the script is run? Thank you.

1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

You need the VMHost parameter, or a ResourcePool or a vApp.

You don't need the Datastore parameter, if the new VM can be created on the same datastore as the source VM.

If you want to override this behavior and use another datastore, you have to use the Datastore parameter.

You can do a Get-VM on the name VM2, and if it exists remove it.

Something like this

$newVMName = "VM1"
$sourceVMName = "VM2"
$esxName = "MyEsx"

Get-VM -Name $newVMName | Remove-VM -DeletePermanently -Confirm:$false
New-VM -Name $newVMName -VM $sourceVMName -VMHost $esxName


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

40 Replies
LucD
Leadership
Leadership
Jump to solution

You need the VMHost parameter, or a ResourcePool or a vApp.

You don't need the Datastore parameter, if the new VM can be created on the same datastore as the source VM.

If you want to override this behavior and use another datastore, you have to use the Datastore parameter.

You can do a Get-VM on the name VM2, and if it exists remove it.

Something like this

$newVMName = "VM1"
$sourceVMName = "VM2"
$esxName = "MyEsx"

Get-VM -Name $newVMName | Remove-VM -DeletePermanently -Confirm:$false
New-VM -Name $newVMName -VM $sourceVMName -VMHost $esxName


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

elihuj
Enthusiast
Enthusiast
Jump to solution

Thanks LucD. I'm going to play around with this in my lab and post results.

Reply
0 Kudos
elihuj
Enthusiast
Enthusiast
Jump to solution

Pretty slick LucD. Worked like a charm!

This is also pretty error proof right? Meaning the only way a VM is going to get overwritten is if it explicitly matches the $newVMName parameter correct?

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

That is correct.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
elihuj
Enthusiast
Enthusiast
Jump to solution

Just a followup question.. I notice when I run the script with credentials in the script, I get some messages once the script completes:

WARNING: 'Description' property is obsolete. Use 'Notes' instead.

WARNING: 'HardDisks' property is obsolete. Use 'Get-HardDisk' cmdlet instead.

WARNING: 'NetworkAdapters' property is obsolete. Use 'Get-NetworkAdapter'

cmdlet instead.

WARNING: 'UsbDevices' property is obsolete. Use 'Get-UsbDevice' cmdlet instead.

WARNING: 'CDDrives' property is obsolete. Use 'Get-CDDrive' cmdlet instead.

WARNING: 'FloppyDrives' property is obsolete. Use 'Get-FloppyDrive' cmdlet

instead.

WARNING: 'Host' property is obsolete. Use 'VMHost' instead.

WARNING: 'HostId' property is obsolete. Use 'VMHostId' instead.

PowerState: PoweredOff

Version: v7

Notes: Cloned by Administrator

NumCpu: 1

MemoryMB: 1024

There is no output when I run the script and supply credentials manually. I assume this is safe to ignore?

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

These are just warnings. They are there to inform you which properties might disappear in a future release, and hence not to use them anymore in your scripts.

You can suppress them by using the DisplayDepreciationWarnings switch on the Set-PowerCLIConfiguration cmdlet.

The New-VM cmdlet will place the PowerCLI object for the newly created VM in the pipeline.

Those are the 5 last lines you see in the output.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

elihuj
Enthusiast
Enthusiast
Jump to solution

Excellent. Thank you again LucD.

Reply
0 Kudos
elihuj
Enthusiast
Enthusiast
Jump to solution

I noticed this message today when I ran the script:

Remove-VM - An item with the same key has already been added.

+ Get-VM -Name $newVMName | Remove-VM <<<< -DeletePeremanently -Confirm:$false

     + Category Info               : NotSpecified: (:) [Remove-VM], ViError

     + FullyQualifiedErrorID    : Client20_MoServiceImpl_Remove_SingleObject_ViError,VMware.VImAutomation.ViCore.Cmdlets.Commands.RemoveVM

The script does its job correctly though. What does this error mean?

Reply
0 Kudos
SatishRayala
Contributor
Contributor
Jump to solution

Hi,

This is really quick and great script,

I am looking for similar kind of script to create a template by cloning a VM and Delete the Old template on regular basis.

Thanks

VCP

Reply
0 Kudos
rolltidega
Contributor
Contributor
Jump to solution

Hey Luc, what if I want to clone the VM but not specify a VMHost since I am using a cluster of 10 hosts?  Or does that really even matter since at power on it would move to whatever server it thinks is best for it.

Shawn Cannon
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Did you try specifying a ResourcePool instead of a VMHost ?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
MicroMarket
Contributor
Contributor
Jump to solution

elihuj escreveu:

I'm looking to create a PowerCLI script to clone a VM, and overwrite any existing clones that are present. Just doing some searching, here is what I found:

New-VM -Name VM2 -VM VM1 -Datastore datastorename -vmhost hostname

I have not tested the script yet, but it does look like it will do at least part of what I am looking to accomplish. Do I need to use the Datastore and VMhost parameters? And is there anything I can do to delete any existing clones before the script is run? Thank you.

Dear Friends

in what place this script Works ?


how im can execute this script ?

Thanks

Almir

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

You will have to install the PowerCLI module/pssnapin on a Windows box that has the required prerequisites (see the Release Notes).

Then you start the PowerCLI prompt, and run the script, that you saved in a .ps1 file.

See XtraVirt's Beginner's Guide for a good description on starting with PowerCLI.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
MicroMarket
Contributor
Contributor
Jump to solution

LucD wrote:

You will have to install the PowerCLI module/pssnapin on a Windows box that has the required prerequisites (see the Release Notes).

Then you start the PowerCLI prompt, and run the script, that you saved in a .ps1 file.

See XtraVirt's Beginner's Guide for a good description on starting with PowerCLI.

Dear Friend

im have windows powershell ISE installed in mywindows 8

im need any additional resource or plugin ???

but what is the module/pssnapin ????

Thanks

Almir

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Did you read the document I pointed to ?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
MicroMarket
Contributor
Contributor
Jump to solution

Dear Friend

Im download the pdf and follow all steps

im run the Vmware PowerCli and all commands such as Get-VM, Start-VM and Stop-VM worked successfully


when im open script and copy all lines all steps works fine

but im don´t now how im can call the script called .psc1


Im do the script but how im can call the script direct from cmd ???

im try this line bellow


C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe -PSConsoleFile “C:\Programiles\VMware\Infrastructure\VSphere PowerCLI\vim.psc1” -NoExit –Command

Thanks

Almir

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

The .psc1 file is what is called a PSConsoleFile, it is used to load PSSnapins.

The powershell.exe command has multiple options (you can do powershell.exe /? to see them).

If your script is stored in a .ps1 file, you can use the File parameter to run it.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
MicroMarket
Contributor
Contributor
Jump to solution

LucD escreveu:

The .psc1 file is what is called a PSConsoleFile, it is used to load PSSnapins.

The powershell.exe command has multiple options (you can do powershell.exe /? to see them).

If your script is stored in a .ps1 file, you can use the File parameter to run it.

Dear LucD

Great !! The Parameter -File works

Now im ant to test the script line per line

My script is that bellow. but im have another problem

See bellow the blue lines

When im insert the while apears two arrows >> in the lef side

and im cannot exit of this to continue insert anothers lines of the script

how im can do ?? is normal ????

$tgtEsxName = "ESXI HOST" #ESXI Host you want to clone to

$tgtDatastoreName = "DATASTORE" #Datastore you want to clone to

$Vc = "mcb-vcenter" #Name of Vcenter Server

$vcUser = "USER" # Username for VCENTER

$vcPass = "PASSWORD"# Password for VCENTER

#set up email

$emailSMTP = "IP.IP.IP.IP" #Ip address of SMTP server

$emailfrom = "CLONING@YOURDOMAIN.COM" #From Email

$emailRCpt = "ADMINS@YOURDOMAIN.COM" #Recipient email

$smtp = New-Object Net.Mail.SmtpClient -arg $emailSMTP

# add snapin for VMware

add-pssnapin VMware.VimAutomation.Core

Connect-VIServer -Server $vc -User $vcUser -Password $vcPass # log into server

# import CSV File

$importFrom = "CSV"

$vmPath = "C:\CLONES\CLONES.CSV" #path of CSV

$vmList = Import-csv $vmPath # Retrieve the CSV file

$Lines = Get-Content $vmPath | Measure-Object #count the lines

#count line ins CSV file

$Total = $Lines.Count - 1

#initiate Counters

$i = 0

$ttl = 1

#start loop

  While ($ttl -le $Total) {

   # set date format

   $date = Get-Date -Format "MM/dd/yyyy HH:mm"

Function doDate() {

  $now = Get-Date -Format "ddd MMM yyyy HH:mm:ss"

  Write-Host -NoNewline "`n$now | "}

       

$VM = Get-VM $vmList[$i].Name

$fromVMname = $vm

$newvmname = "$fromVmname $date"

Write-Host "Creating clone of $VM ($ttl of $Total)"

#Command to clone VM

New-VM -Name ($newvmname) -VM ($fromvmname) -Datastore ($tgtDatastoreName) -VMHost ($tgtEsxName) -location ("Remote_clones")

$test = Get-Vm -name $newvmname

#if statement for if Vm is not found

if (!$test){

#vm not found

#else Statement used if the VM is found

else{

$path = "C:\CLONES\$vm.txt"#path of log file REPLACE EVERYTHING BEFORE\$VM.TXT

$deleteVM = Get-Content $path #pull line from log file

Remove-VM $deleteVM -deletepermanently -confirm:$false #remove old clone

Clear-Content $path #Delete content of log file

$newvmname | Out-File $path #put name of new server in log file

}

$i++

$ttl++

}

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

You're missing some closing braces in a couple of code blocks.

Try like this

$tgtEsxName = "ESXI HOST" #ESXI Host you want to clone to

$tgtDatastoreName = "DATASTORE" #Datastore you want to clone to

$Vc = "mcb-vcenter" #Name of Vcenter Server

$vcUser = "USER" # Username for VCENTER

$vcPass = "PASSWORD"# Password for VCENTER

#set up email

$emailSMTP = "IP.IP.IP.IP" #Ip address of SMTP server

$emailfrom = "CLONING@YOURDOMAIN.COM" #From Email

$emailRCpt = "ADMINS@YOURDOMAIN.COM" #Recipient email

$smtp = New-Object Net.Mail.SmtpClient -arg $emailSMTP

# add snapin for VMware

add-pssnapin VMware.VimAutomation.Core

Connect-VIServer -Server $vc -User $vcUser -Password $vcPass # log into server

# import CSV File

$importFrom = "CSV"

$vmPath = "C:\CLONES\CLONES.CSV" #path of CSV

$vmList = Import-csv $vmPath # Retrieve the CSV file

$Lines = Get-Content $vmPath | Measure-Object #count the lines

#count line ins CSV file

$Total = $Lines.Count - 1

#initiate Counters

$i = 0

$ttl = 1

#start loop

While ($ttl -le $Total) {

  # set date format

  $date = Get-Date -Format "MM/dd/yyyy HH:mm"

}

Function doDate() {

  $now = Get-Date -Format "ddd MMM yyyy HH:mm:ss"

  Write-Host -NoNewline "`n$now | "

}

$VM = Get-VM $vmList[$i].Name

$fromVMname = $vm

$newvmname = "$fromVmname $date"

Write-Host "Creating clone of $VM ($ttl of $Total)"

#Command to clone VM

New-VM -Name ($newvmname) -VM ($fromvmname) -Datastore ($tgtDatastoreName) `

-VMHost ($tgtEsxName) -Location "Remote_clones"

$test = Get-Vm -name $newvmname

#if statement for if Vm is not found

if (!$test){

  #vm not found

 

}

else{

  #else Statement used if the VM is found

  $path = "C:\CLONES\$vm.txt"#path of log file REPLACE EVERYTHING BEFORE\$VM.TXT

  $deleteVM = Get-Content $path #pull line from log file

  Remove-VM $deleteVM -deletepermanently -confirm:$false #remove old clone

  Clear-Content $path #Delete content of log file

  $newvmname | Out-File $path #put name of new server in log file

}

$i++

$ttl++


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos