我正在尝试编写(powershell / powercli)克隆我们的QA环境(261台服务器)。 基本上我想创建每个服务器的新副本,只需更改VM名称,主机名和IP地址。理想情况下,我想在域上使用新克隆(其中90%是Windows操作系统)。我的许多服务器都有许多大型硬盘驱动器,这些硬盘驱动器并不都适用于一个数据存储区,因此我必须能够克隆到多个数据存储区。
我开始使用New-VM来获得足够小的服务器以适应一个数据存储,但OSCustomization仅在大约30%的时间内工作。其余的时间我必须登录到Windows并手动从域中删除以重命名主机名。大多数时候Set-OSCustomizationNicMapping工作但是指定-Domain -DomainUsername / Password永远不会工作(充其量它重命名服务器并放入“域名”工作组,但它永远不会将它连接到域)。
要解决多数据存储问题,我发现$ vm.ExtensionData.CloneVM使用VMWare.Vim.VirtualMachineRelocateSpec来指定哪些硬盘驱动器去哪些数据存储并且效果很好,但我不知道如何自定义主机名或NIC设置
因此基本要求是:克隆到多个数据存储区,更改主机名和IP设置。有没有人有任何建议或解决方案?
以下是我的一些代码段:
为New-VM设置OSCustomizationSpec
$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
New-VM命令:
$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
这是多数据存储克隆:
$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)
我猜测使用ExtensionData.CloneVM方法的下一步是声明CustomizationIdentitySettings的新对象,但我找到的文档(http://pubs.vmware.com/vi3/sdk/ReferenceGuide/vim.vm.customization.IdentitySettings.html)并没有真正帮助(可能因为设置因人而异)操作系统?)然后将该对象添加到我的$ spec对象。 OSCustomizationNicMapping(http://www.vmware.com/support/developer/PowerCLI/PowerCLI41U1/html/OSCustomizationNicMapping.html)也是如此,但我不能从pubs中获取足够的信息来弄清楚如何构建我的$ spec对象。
答案 0 :(得分:0)
你不能复制到孤立的环境吗?只需构建一组额外(隔离)VLAN并复制所有虚拟机,保留IP /名称,仅在虚拟机级别切换VLAN。
答案 1 :(得分:0)
我终于找到了这个页面:http://www.vmdev.info/?p=202 我从他们展示的示例开始,它起作用,所以我一直在添加CloneSpec字段,直到我得到我想要的:
$nicMaparray = @()
$FirstNic = New-Object VMware.Vim.CustomizationAdapterMapping
$FirstNic.adapter = New-Object VMware.Vim.CustomizationIPSettings
$FirstNic.adapter.dnsDomain = $domain
$FirstNic.adapter.dnsServerList = "10.26.40.115","10.26.40.116"
$FirstNic.adapter.gateway = $DefGW
$FirstNic.adapter.ip = New-Object Vmware.Vim.CustomizationFixedIp
$FirstNic.adapter.ip.IpAddress = $NewIP
$FirstNic.adapter.subnetMask = "255.255.248.0"
$nicMaparray += $FirstNic
$folderobj = $origvm.parent
$vm = Get-VM $sourceName | Get-View
$cloneName = $targetName
$cloneFolder = Convert-PathToFolderObject -FolderPath $folderpath
$cloneSpec = new-object Vmware.Vim.VirtualMachineCloneSpec
$cloneSpec.Location = new-object Vmware.Vim.VirtualMachineRelocateSpec
$cloneSpec.Location.Host = (Random(Get-VMHost | Where {$_.Name -like "*esxiqa*"}) | get-view).MoRef
$targetDatastore = ($MapInfo | Where-Object {$_.Name -eq "Hard disk 1"}).NewDataStore
$cloneSpec.Location.Datastore = (Get-Datastore $targetDatastore | get-view).MoRef
$cloneSpec.customization = New-Object VMware.Vim.CustomizationSpec
$cloneSpec.customization.globalIPSettings = New-Object VMware.Vim.CustomizationGlobalIPSettings
$cloneSpec.customization.globalIPSettings.dnsServerList = "10.26.40.115","10.26.40.116"
$cloneSpec.customization.identity = New-Object VMware.Vim.CustomizationSysprep
# $spec.customization.identity.guiRunOnce = New-Object VMware.Vim.CustomizationGuiRunOnce
$cloneSpec.customization.identity.guiUnattended = New-Object VMware.Vim.CustomizationGuiUnattended
$cloneSpec.customization.identity.guiUnattended.autoLogonCount = 0
$cloneSpec.customization.identity.guiUnattended.password = New-Object VMware.Vim.CustomizationPassword
$cloneSpec.customization.identity.guiUnattended.password.plainText = $true
$cloneSpec.customization.identity.guiUnattended.password.value = Get-Password -Username "Administrator"
$cloneSpec.customization.identity.identification = New-Object VMware.Vim.CustomizationIdentification
$cloneSpec.customization.identity.identification.joinWorkgroup = "WORKGROUP"
# $spec.customization.identity.licenseFilePrintData = $null
$cloneSpec.customization.identity.userData = New-Object VMware.Vim.CustomizationUserData
$cloneSpec.customization.identity.userData.computerName = New-Object VMware.Vim.CustomizationFixedName
$cloneSpec.customization.identity.userData.computerName.name = $cloneName
$cloneSpec.customization.identity.userData.productID = $ProductKey
$cloneSpec.customization.nicSettingMap = $nicMaparray
#nicMaparray build above
# $cloneSpec.customization.options = $null
$cloneSpec.powerOn = $true
Get-HardDisk -VM $sourceName | %{
$disk = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator
$disk.diskId = $_.ExtensionData.Key #2001,2002,2003,...
$DiskLabel = $_.ExtensionData.DeviceInfo.Label
$dsname = ($MapInfo | Where-Object {$_.Name -eq $DiskLabel}).NewDataStore
$ds = Get-Datastore -Name $dsname
$disk.datastore = $ds.id
$cloneSpec.Location.Disk += $disk
}
Write-Verbose "Cloning $sourceName"
try
{
$vm.CloneVM( $cloneFolder, $cloneName, $cloneSpec)
return $true
}
catch
{
$_.Exception
return $false
}