VMware Cloud Community
Silck
Contributor
Contributor

Clone existing VM to Specific Data Store without affecting/ powering off existing VM

Hi Guys, If someone could assist with below ask it would be greatly appreciated. 

Use case: (Powercli)

I need to clone 20 + existing production VM on a different Data Store without affecting/powering off production VM's. They are are currently on same cluster. Clone VM should be powered off & NIC should be on VM network. 

20 + servers will be divided in 3 or 4 Data stores so the idea is server names should be coming from text file.

$ VM = get-content "c:\temp\vm.txt"

Some of the existing VM's has additional disk attached to it. (i.e. c:\\,d:\\) All the VM's are windows OS. Hoping to run this from windows host with powecli on it. 

Additional ask: Not a requirement but if somehow list of cloned vm's with new cloned vmname's and new datastore name can be exported as csv or output. 

 

 

0 Kudos
9 Replies
LucD
Leadership
Leadership

This is basically a New-VM with the CloneVM parameterset, which allows you to specify the Datastore and the Name of the new VM.
Not sure what the remark about the C:\ and 😧 drives means, neither does the type of Guest OS matter.

What is the problem?
What exactly is in the file containing the VMnames and DatastoreNames?


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

0 Kudos
Silck
Contributor
Contributor

Hi LucD, 

Thanks for you prompt response. Sorry to confuse you with Disk and OS - I understood your point there. Lets keep the OS and disk apart.

There is no issue as of now - All I am looking for is a powecli command or script which can help me clone 20 existing vm's to a different data store. I do not want to affect or shutdown existing vm's (the one i am cloning from) as they are in production. My text file contains vm names only.I have total of 4 datastore that I want to use for cloning 20+ vms. I was hopping if datastore name can come from variable. But if you think it can be done through same text file by adding datastore names along with VM names it would be great. It just i have no clue how to do that. 

Text file :

server1

server2

server3 

0 Kudos
LucD
Leadership
Leadership

How do you intend those pick one of those 4 datastores for the clone?
Do you pick one randomly?
Or the one with the most free space?

The simplest form, with a random destination datastore and on the same ESXi node, could be something like this

$dsNames = 'DS1','DS2','DS3','DS4'

Get-Content -Path .\vmnames.txt -PipelineVariable row |
ForEach-Object -Process {
    $vm = Get-VM -Name $row
    New-VM -Name "$($row)-Clone" -VM $vm -Datastore (Get-Random $dsNames) -VMHost $vm.VMHost
}


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

0 Kudos
Silck
Contributor
Contributor

Actually we identified which vm goes on which data store.

server1 to 5 - goes to datastore 1

server6 to 10 - goes to datastore 2

server11 to 15 - goes to datastore 3

server16 to 20 - goes to datastore 4

0 Kudos
LucD
Leadership
Leadership

Then you could do something like this

$dsNames = 'DS1','DS2','DS3','DS4'

$count = 0
Get-Content -Path .\vmnames.txt -PipelineVariable row |
ForEach-Object -Process {
    $vm = Get-VM -Name $row
    $ds = $dsNames[[math]::Floor($count/5)]
    New-VM -Name "$($row)-Clone" -VM $vm -Datastore $ds -VMHost $vm.VMHost
    $count++
}


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

0 Kudos
Silck
Contributor
Contributor

Thanks I will test this today. Just one last question. If we are to get data store name from same text file as well than is it more work.

0 Kudos
LucD
Leadership
Leadership

How would you do that?
The first 4 lines in the text file?
Easiest would be a separate text file with only the datastorenames.


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

0 Kudos
Silck
Contributor
Contributor

Yes Separate file with Datastore name.

0 Kudos
LucD
Leadership
Leadership

That is only a small change

$dsNames = Get-Content -Path .\dsnames.txt

$count = 0
Get-Content -Path .\vmnames.txt -PipelineVariable row |
ForEach-Object -Process {
    $vm = Get-VM -Name $row
    $ds = $dsNames[[math]::Floor($count/5)]
    New-VM -Name "$($row)-Clone" -VM $vm -Datastore $ds -VMHost $vm.VMHost
    $count++
}


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

0 Kudos