Skip to content
Browse files

Script for cloning VM's on ESX 4 and ESXi5 servers not managed by vCe…

…nter
  • Loading branch information...
1 parent 5e1d845 commit ad5de1a5f300ca2bc26b81fbba5b5614ea0b2a26 @darkoperator committed Mar 9, 2012
Showing with 145 additions and 0 deletions.
  1. +145 −0 clone_vm.ps1
View
145 clone_vm.ps1
@@ -0,0 +1,145 @@
+######################################################################################################################
+# File: clone_vm.ps1 #
+# Author: Carlos Peres #
+# Email: carlos_perez@darkoperator.com #
+# Copyright: © 2012 . All rights reserved. #
+# Usage: To load this module in your Script Editor: #
+# 1. Open PowerCli shell. #
+# 2. Navigate to where the script is located. #
+# 3. Call script with options. .\clone_vm.ps1 -Server <ESX or vCenter> -VM <VM to Clone> -CloneName #
+# <Name to give to Clone VM> <Enter> #
+# License: BSD 3 Clause License #
+#######################################################################################################################
+# Define Script Parameters
+param
+(
+ [string]$Server,
+ [string]$VM,
+ [string]$CloneName
+)
+
+# Check Paramters
+if ($Server -eq $null)
+{
+ $Host.UI.WriteErrorLine("[-] You must specify a server wher the VM to clone is located.")
+ exit
+}
+if ($VM -eq $null)
+{
+ $Host.UI.WriteErrorLine("[-] You must specify a Powered Off VM name to Clone.")
+}
+if ($CloneName -eq $null)
+{
+ $Host.UI.WriteErrorLine("[-] You must specify a name for the clone.")
+}
+# Check if VMware Snappin is loaded for when ran outside of PowerCli
+if ( (Get-PSSnapin -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue) -eq $null )
+{
+ Write-Host "[*] VMware Automation Snapin is not loaded, attempting to load..." -ForegroundColor Green
+ Try {
+ Add-PsSnapin VMware.VimAutomation.Core | Out-Null
+ } Catch {
+ $Host.UI.WriteErrorLine("[-] Could not load snapping check that PowerCli is installed.")
+ exit
+ }
+}
+
+#verify we're connected to a VM host
+ Try {
+ if (get-vmhost -Server $Server -State connected -erroraction "Stop") {
+ $connected=$True
+ }
+ }
+ Catch {
+ #Try to connect
+ Try {
+ Write-Host -ForegroundColor Green "[*] Connecting to $Server"
+ $viserver=Connect-VIserver -Server $Server -errorAction "Stop"
+ $connected=$True
+ }
+ Catch {
+ $msg="[-] Failed to connect to server $Server"
+ Write-Warning $msg
+ Write-Warning $error[0].Exception.Message
+ }
+ }
+
+# Function Returns hash with datastore name and folder name
+function find_vm {
+ param($vm_name)
+ $vm_info =@{}
+ $orig_vm = Get-VM | where {$_.name -match $vm_name}
+
+ if ($orig_vm -ne $null){
+ if ($orig_vm.PowerState -eq "PoweredOff"){
+ $vm_info_raw = $orig_vm.Extensiondata.Summary.Config.VmPathName.Split(" ")
+ $vm_info['datastore'] = $vm_info_raw[0] -creplace "\[|\]", ""
+ $vm_info['folder'] = $vm_info_raw[1].split("/")[0]
+ }
+ else {
+ $Host.UI.WriteErrorLine("[-] VM must be powered off before attempting to clone")
+ }
+ }else {
+ $Host.UI.WriteErrorLine(" [-] Could not find the VM specified")
+ exit
+ }
+ $vm_info
+}
+
+function clone {
+ param($dsstore, $fs_folder, $clone_name, $vmhost)
+ # Generate PSDrive
+ $datastore = Get-Datastore $dsstore
+ # Check if a previous PSDrive exists
+ $psd = Get-PSDrive | where {$_.name -eq "dd"}
+ if ($psd -eq $null){
+ $ds_path = New-PSDrive -Location $datastore -Name vmds -PSProvider VimDatastore -Root "\"
+ }
+ Write-Host "[*] Making copy of VM as $clone_name (Depending size, number of files and server load it may take a while)" -ForegroundColor Green
+ Copy-DatastoreItem -Item "vmds:\$fs_folder\*" -Destination "vmds:\$clone_name\" -Force
+ Write-Host "[*] Registering $clone_name" -ForegroundColor Green
+ dir "vmds:\$clone_name\*.vmx" | %{New-VM -Name $clone_name -VMFilePath $_.DatastoreFullPath -VMHost $vmhost} | Out-Null
+ Write-Host "[*] VM has been cloned!" -ForegroundColor Green
+ Write-Host "[*] Cleaning up remaining tasks" -ForegroundColor Green
+ Remove-PSDrive -Name "vmds"
+}
+
+# Function to check if a VM already exists
+function check_vm {
+ param($clone_name, $exiting_vm)
+ $to_clone = $found_vm = Get-VM | where {$_.name -eq $exiting_vm}
+ if ($found_vm -ne $null) {
+ $Host.UI.WriteErrorLine("[-] VM $VM specified does not exist on this server!")
+ exit
+ }
+ $found_vm = Get-VM | where {$_.name -eq $clone_name}
+ if ($found_vm -ne $null) {
+ $Host.UI.WriteErrorLine("[-] VM $clone_name already exists on this server")
+ exit
+ }
+}
+
+# Function to change VM UUID
+function change_uuid{
+ param($cloned_vm)
+ $key = "uuid.action"
+ $value = "create"
+ Write-Host "[*] Changing the VM UUID of the cloned VM" -ForegroundColor Green
+ $vm = get-vm $cloned_vm
+ $vm_id = Get-View $vm.Id
+ $vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
+ $vmConfigSpec.extraconfig += New-Object VMware.Vim.optionvalue
+ $vmConfigSpec.extraconfig[0].Key=$key
+ $vmConfigSpec.extraconfig[0].Value=$value
+ $vm_id.ReconfigVM($vmConfigSpec)
+ Write-Host "[*] UUID Changed" -ForegroundColor Green
+}
+########## MAIN ##########
+
+if ($connected) {
+ Write-Host "[*] Cloning $VM as $CloneName" -ForegroundColor Green
+ check_vm $CloneName
+ $vmhash = find_vm $VM
+ clone $vmhash['datastore'] $vmhash['folder'] $CloneName $Server
+ change_uuid $CloneName
+}

0 comments on commit ad5de1a

Please sign in to comment.
Something went wrong with that request. Please try again.