-
Notifications
You must be signed in to change notification settings - Fork 56
/
clone_vm.ps1
146 lines (136 loc) · 5.77 KB
/
clone_vm.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
######################################################################################################################
# File: clone_vm.ps1 #
# Author: Carlos Peres #
# Email: [email protected] #
# 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> -VM <VM to Clone> -CloneName #
# <Name to give to Clone VM> <Enter> #
# License: BSD 3 Clause License #
# Version: 0.3 #
#######################################################################################################################
# Define Script Parameters
param
(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty]
[string]$Server,
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty]
[string]$VM,
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty]
[string]$CloneName
)
# 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"} | select -First 1
if ($orig_vm -ne $null){
if ($orig_vm.PowerState -eq "PoweredOff"){
$vm_info_raw = $orig_vm.Extensiondata.Summary.Config.VmPathName.Split(" ",2)
$vm_info['datastore'] = $vm_info_raw[0] -creplace "\[|\]", ""
$vm_info['folder'] = $vm_info_raw[1].split("/")[0]
$VM_info['vmhost'] = $orig_vm.VMHost
}
else {
$Host.UI.WriteErrorLine("[-] VM must be powered off before attempting to clone")
exit
}
}
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 "vmds"}
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
Write-Warning "This script creates a clone with disks in thick type."
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
write $vmhash['folder']
clone $vmhash['datastore'] $vmhash['folder'] $CloneName $vmhash['vmhost']
#change_uuid $CloneName
}