After posting yesterday about modifying the parent image to allow for hostname changes, I was still looking for something a little more streamlined. I remember reading about the new REST API that is available on workstation, so I wrote a little script to use the Workstation API to clone a VM.
Also just FYI – this performs a full clone, not a linked clone. I’m not sure that linked clone functionality is available via the API yet. I’m hoping to use the vmrun command to accomplish this, and while I know it is packaged with Workstation Pro, the only documentation I can find for it is associated with Fusion. I also have been thinking about using vagrant for this as well.
This is very basic functionality, and exists simply to showcase the functionality. There’s no error checking, and it could be expanded a lot. Regardless, enjoy!
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
|
<#
Original Links:
https://github.com/jonhowe/Virtjunkie.com/blob/master/clone-workstation-vm.ps1
http://www.virtjunkie.com/clone-vm-in-workstation-15-pro-via-rest-api-using-powershell/
The API will need to be running. Use this link to configure it.
https://docs.vmware.com/en/VMware-Workstation-Pro/15.0/com.vmware.ws.using.doc/GUID-C3361DF5-A4C1-432E-850C-8F60D83E5E2B.html
#>
$user = '[Username]'
$pass = '[Password]'
$VMToClone = "[Template Name To Clone]"
$newvmname = "[New VM Name]"
$REST_URL = "https://[Your IP and port]/api/vms"
function Select-VM {
param (
$vmname
)
$rs=Invoke-WorkstationRestRequest -method Get
foreach ($vm in $rs)
{
$pathsplit = ($vm.path).split("/")
$vmxfile = $pathsplit[($pathsplit.Length)-1]
$thisVM = ($vmxfile).split(".")[0]
if ($thisVM -eq $vmname) { return $vm;break}
}
}
function Select-OneVM {
param (
$vmid
)
$rs=Invoke-WorkstationRestRequest -method Get -uri ($REST_URL + "/$($vmid.id)")
return $rs
}
function Set-Credentials {
param (
$username,
$password
)
$pair = "${username}:${password}"
$bytes = [System.Text.Encoding]::ASCII.GetBytes($pair)
$base64 = [System.Convert]::ToBase64String($bytes)
$basicAuthValue = "Basic $base64"
return $basicAuthValue
}
function New-WorkstationVM {
param (
$sourcevmid,
$newvmname
)
$body = @{
'name' = $newvmname;
'parentId' = $sourcevmid
}
$requestbody = ($body | ConvertTo-Json)
$rs=Invoke-WorkstationRestRequest -method "POST" -body $requestbody
return $rs
}
function Invoke-WorkstationRestRequest {
param (
$uri=$REST_URL,
$method,
$body=$null
)
$headers = @{
'authorization' = $basicAuthValue;
'content-type' = 'application/vnd.vmware.vmw.rest-v1+json';
'accept' = 'application/vnd.vmware.vmw.rest-v1+json';
'cache-control' = 'no-cache'
}
$rs=Invoke-RestMethod -uri $uri -Headers $headers -SkipCertificateCheck -Method $method -Body $body
return $rs
}
$creds = Set-Credentials -username $user -password $pass
$vmtoclone = Select-VM -vmname $VMToClone
$result=New-WorkstationVM -sourcevmid $VMToClone.id -newvmname $newvmname
$newvm = select-onevm -vmid $result
return $newvm
|