【问题标题】:clone vm change network identity克隆 vm 更改网络标识
【发布时间】:2013-08-19 01:11:05
【问题描述】:

我正在尝试编写脚本 (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 设置。有没有人有任何建议或解决方案?

这是我的一些代码 sn-ps:

为 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 对象。

【问题讨论】:

    标签: powershell clone vmware powercli


    【解决方案1】:

    我终于找到了这个页面: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
        }
    

    【讨论】:

      【解决方案2】:

      你不能复制到一个孤立的环境吗?只需构建一组额外(隔离)的 VLAN 并复制所有 VM,保留 IP/名称,仅在 VM 级别切换 VLAN。

      【讨论】:

      • 感谢您的评论。不幸的是,我不能做一个隔离的环境,因为许可和大小问题,我的一些服务器是单实例的,而我正在克隆的服务器必须能够路由到相同的单实例。
      • 我为一家大医院建造了这样的东西。他们需要一个 OTA 环境,在这个环境中,他们可以拥有生产虚拟机的精确副本。我不允许更改虚拟机的 IP 地址。我构建了一个单独的 VLAN,在其中部署了 VM,并将 vShield Edge 防火墙作为 NAT 路由器插入。这样,测试环境中的机器仍然可以访问这些服务器。当然,他们的大型癌症治疗扫描仪(价值超过 100 万欧元)无法复制,所以我在它前面放了一个额外的 NAT 路由器。根据场景,它会路由到 prod 或 test。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-13
      相关资源
      最近更新 更多