I'm trying to script (powershell/powercli) the cloning of our QA environment (261 servers). Basically I want to make a new copy of each server just changing the VM name, the hostname, and the IP address. Ideally I'd want the new clone on the domain (90% of them are Windows OS). And many of my servers have many large hard drives that won't all fit on one datastore so I have to be able to clone to multiple datastores.
I started off with New-VM for the servers that were small enough to fit on one datastore, but OSCustomization only works about 30% of the time. The rest of the time I have to login to Windows and manually remove from the domain to rename the hostname. Most of the time Set-OSCustomizationNicMapping works But specifying -Domain -DomainUsername/Password never works (at best it renames the server and puts in the "domain-name" workgroup but it never joins it to the domain).
To workaround the multidatastore issue I discovered $vm.ExtensionData.CloneVM using VMWare.Vim.VirtualMachineRelocateSpec to specify which hard drives go to which datastores and that works great, but I don't know how to customize the hostname or NIC settings.
So the basic requirements are: clone to multiple datastores changing hostname and IP settings. Does anyone have any recommendations or solutions?
Here's some of my code snippets:
Setting up the OSCustomizationSpec for New-VM
$spec = New-OSCustomizationSpec -Name "PowerCLI Scripting for $NewHostName" -Spec "PowerCLI Scripting" -WhatIf:$False
Set-OSCustomizationSpec $spec -Workgroup "WORKGROUP" -DomainUsername "qajoin@qa.company.com" -DomainPassword (Get-Password -Username "qa\qajoin") -ProductKey $ProductKey -AdminPassword (Get-Password $Script:LuserName) | Out-Null
Get-OSCustomizationSpec "PowerCLI Scripting for $NewHostName" `
| Get-OSCustomizationNicMapping `
| Set-OSCustomizationNicMapping `
-IPMode:UseStaticIP `
-IPAddress $NewIPAddress `
-SubnetMask "255.255.248.0" `
-DNS "10.26.40.115","10.26.40.116" `
-DefaultGateway $NewDFGW | Out-Null
The New-VM command:
$VM = New-VM -VMHost $VMHost -VM $Hostname -Name $NewHostName -Description "$Description" -OSCustomizationSpec "PowerCLI Scripting for $NewHostName" -Location (Get-Folder -Id $Location) -Datastore $MostFreeSpace -ErrorAction Stop
Here's the multi-datastore clone:
$VMXtargetDatastore = Get-Datastore ($MapInfo | Where-Object {$_.Name -eq "Hard disk 1"}).NewDataStore
#Create an empty CloneSpec
$spec = New-Object VMware.Vim.VirtualMachineCloneSpec
$spec.Template = $false
$spec.PowerOn = $false
#Create a RelocateSpec (datastore is target for .vmx)
$spec.Location = New-Object VMware.Vim.VirtualMachineRelocateSpec
$spec.Location.Datastore = $targetDatastore.ExtensionData.MoRef
#For each disk in the current vm
# create a new DiskLocator spec
# populate the datastore and diskid from the current harddisk
# add the spec to RelocateSpec from above
Get-HardDisk -VM $Origvm | %{
$disk = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator
$disk.diskId = $_.ExtensionData.Key #2001,2002,2003,...
$DiskLabel = $_.ExtensionData.DeviceInfo.Label
#$disk.datastore = $_.ExtensionData.Backing.Datastore #type=datastore value=datastore-2790
$dsname = ($MapInfo | Where-Object {$_.Name -eq $DiskLabel}).NewDataStore
$ds = Get-Datastore -Name $dsname
$disk.datastore = $ds.id
$spec.Location.Disk += $disk
}
$CustSpec = New-Object VMware.Vim.CustomizationSpec
$origvm.ExtensionData.CloneVM((Get-Folder -Id $folder).ExtensionData.MoRef, $targetName, $spec)
I'm guessing the next step using the ExtensionData.CloneVM method is to declare a new object of CustomizationIdentitySettings but the documentation (http://pubs.vmware.com/vi3/sdk/ReferenceGuide/vim.vm.customization.IdentitySettings.html) that I could find isn't really helpful (probably because the settings vary by OS?) and then add that object to my $spec object. Same would go for OSCustomizationNicMapping (http://www.vmware.com/support/developer/PowerCLI/PowerCLI41U1/html/OSCustomizationNicMapping.html) but I can't suss enough information out of the pubs to figure out how to build my $spec object.