Solved

VMWare ESXi - Linked clone, need to move parent to different datastore

Posted on 2015-02-14
4
539 Views
Last Modified: 2015-02-14
Experts,

In all of my searching in dealing with Linked clones and moving them to different datastores, the writeups always involve moving the cloned machine.  I've been trying to see if the following is possible without hurting anything:

1.  Shut down all linked-clone VMs that use the parent disk in question
2.  Once everything is shut down, move the parent disk to an entirely different datastore
3.  Modify the linked VM's cfg to point to the updated parent location
          *This would mean that the child is on a completely different datastore than the parent
4.  Fire the linked clone VMs back up
5.  Take the rest of the month off

5 may be a bit too much, but if somebody has any information on whether or not it's even possible and safe to do the above items (1-4), I would be greatly appreciated.  This is in an effort to add some administrative/logical separation between datastore objects, and doing some general housekeeping on storage.

For the record, the only utility I'm using, is my VCenter appliance.  All of the linked clones were created using my home-grown script here:

//================================================================================
# *****************************************
# *** <DOMAIN> VM Clone Creation Script ***
# *****************************************

# ---------------------------------------------

# User Defined Variables
      $strVCenterHost = "<VC HOST>"
      $strOSDataStore = "iSCSI_VMFS_OS"
      $strSecondaryDataStore = "iSCSI_VMFS_Secondary"
      $strOSDataStoreVMFolder = "vm"
      $strWorkingDir = "C:\Temp\CreateVM\VMWare\LinkedClone\"

# ----------------------------------------------

# On Screen Menu
      Clear-Host
      Write-Host "*****************************************"
      Write-Host "*** <DOMAIN> VM Clone Creation Script ***"
      Write-Host "*****************************************"
      Write-Host ""
      $strVCenterHost = Read-Host "VCenter Server"
      $strUserName = Read-Host "Username that has access to create virtual machine"
      $strInputPassword = Read-Host -AsSecureString "Password for the above account"
      $strInputPassword = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($strInputPassword)
      $strPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($strInputPassword)

      [Int]$intBaseChoice = 0
      While ($intBaseChoice -lt 1 -OR $intBaseChoice -gt 4) {
            Write-Host ""
            Write-Host "      1.  Server 2012 R2 Std Core"
            Write-Host "      2.  Server 2012 R2 Std Full"
            Write-Host "      3.  Ubuntu Server 14.04"
            Write-Host "      4.  Untangle NG Firewall 10.2"
            Write-Host ""
            [Int]$intBaseChoice = Read-Host "Please select the base VM"
      }
      #Valid nic options:  Unknown, e1000, Flexible, Vmxnet, EnhancedVmxnet, Vmxnet3
      Switch( $intBaseChoice ) {
            1 { $strBaseOption = "BaseLine_Server2k12_R2_Std_Core"
                  $strNicType = "Vmxnet3"
                  }
            2 { $strBaseOption = "BaseLine_Server2k12_R2_Std_Full"
                  $strNicType = "Vmxnet3"
                  }
            3 { $strBaseOption = "BaseLine_UbuntuServer_14.04"
                  $strNicType = "Vmxnet3"
                  }
            4 { $strBaseOption = "BaseLine_UntangleNGFirewall_10.2"
                  $strNicType = "e1000"
                  }
      }

      [Int]$intMemoryChoice = 0
      While ($intMemoryChoice -lt 1 -OR $intMemoryChoice -gt 7) {
            Write-Host ""
            Write-Host "      1.  256 Mb"
            Write-Host "      2.  512 Mb"
            Write-Host "      3.  1024 Mb"
            Write-Host "      4.  2048 Mb"
            Write-Host "      5.  4096 Mb"
            Write-Host "      6.  8192 Mb"
            Write-Host "      7.  16384 Mb"
            Write-Host ""
            [Int]$intMemoryChoice = Read-Host "Please select the memory amount"
      }
      Switch( $intMemoryChoice ) {
            1 { $strMemoryOption = "256" }
            2 { $strMemoryOption = "512" }
            3 { $strMemoryOption = "1024" }
            4 { $strMemoryOption = "2048" }
            5 { $strMemoryOption = "4096" }
            6 { $strMemoryOption = "8192" }
            7 { $strMemoryOption = "16384" }
      }

      [Int]$intProcChoice = 0
      While ($intProcChoice -lt 1 -OR $intProcChoice -gt 4) {
            Write-Host ""
            Write-Host "      1.  1 CPU"
            Write-Host "      2.  2 CPUs"
            Write-Host "      3.  4 CPUs"
            Write-Host "      4.  8 CPUs"
            Write-Host ""
            [Int]$intProcChoice = Read-Host "Please select the # of CPUs"
      }
      Switch( $intProcChoice ) {
            1 { $intProcOption = "1" }
            2 { $intProcOption = "2" }
            3 { $intProcOption = "4" }
            4 { $intProcOption = "8" }
      }

      [Int]$intNetworkChoice = 0
      While ($intNetworkChoice -lt 1 -OR $intNetworkChoice -gt 8) {
            Write-Host ""
            Write-Host "      1.  NET_10.0.0.0/23  Vlan 1"
            Write-Host "      2.  NET_10.0.2.0/23  Vlan 2"
            Write-Host "      3.  NET_10.0.4.0/23  Vlan 4"
            Write-Host "      4.  NET_10.0.6.0/23  Vlan 6"
            Write-Host "      5.  NET_10.0.8.0/23  Vlan 8"
            Write-Host "      6.  NET_10.0.10.0/23  Vlan 10"
            Write-Host "      7.  NET_10.0.12.0/23  Vlan 12"
            Write-Host "      8.  NET_10.0.14.0/23  Vlan 14"
            Write-Host ""
            [Int]$intNetworkChoice = Read-Host "Please select the network access for this machine"
      }
      $strMemoryMin = "256Mb"
      Switch( $intNetworkChoice ) {
            1 { $strNetworkOption = "NET_10.0.0.0/23  Vlan 1" }
            2 { $strNetworkOption = "NET_10.0.2.0/23  Vlan 2" }
            3 { $strNetworkOption = "NET_10.0.4.0/23  Vlan 4" }
            4 { $strNetworkOption = "NET_10.0.6.0/23  Vlan 6" }
            5 { $strNetworkOption = "NET_10.0.8.0/23  Vlan 8" }
            6 { $strNetworkOption = "NET_10.0.10.0/23  Vlan 10" }
            7 { $strNetworkOption = "NET_10.0.12.0/23  Vlan 12" }
            8 { $strNetworkOption = "NET_10.0.14.0/23  Vlan 14" }
      }

      [Int]$intSecondaryHDChoice = 0
      While ($intSecondaryHDChoice -lt 1 -OR $intSecondaryHDChoice -gt 2) {
            Write-Host ""
            Write-Host "      1.  Yes"
            Write-Host "      2.  No"
            Write-Host ""
            [Int]$intSecondaryHDChoice = Read-Host "Secondary hard drive requirement"
      }
      Switch( $intSecondaryHDChoice ) {
            1 { $strSecondaryHDChoice = "Yes" }
            2 { $strSecondaryHDChoice = "No" }
      }
      Write-Host ""
      $strVMClient = Read-Host 'Please provide the virtual machine name'

# ---------------------------------------------

# Process VM Creation
      Write-Host ""
      Write-Host "Creating VM based on requirements..."
      # ---------------------------------------------
      Write-Host "Creating temporary working directory"
      $strWorkingDirClone = "$strWorkingDir\$strVMClient"
      $strWorkingDirOrig = "$strWorkingDir\$strBaseOption"
      If (!(Test-Path -Path "$strWorkingDirClone" )){
          New-Item -ItemType Directory -Path "$strWorkingDirClone" | Out-Null
      }
      # ---------------------------------------------
      Write-Host "Loading PowerCLI snapin and assemblies"
      Add-PSSnapin VMWare.VimAutomation.Core | Out-Null
      [Reflection.Assembly]::LoadWithPartialName("vmware.vim") | Out-Null
            Write-Host "Connecting to server instance $strVCenterHost"
            Connect-VIServer -Server $strVCenterHost -User "$strUserName" -Password "$strPassword" -WarningAction SilentlyContinue | Out-Null
            Write-Host "Gathering datastore object"
            $objDataStore = Get-Datastore $strOSDataStore
            $strOSDataStoreURL = $objDataStore.ExtensionData.Info.Url -Replace "ds://", ""
            $strParentFileNameHint = "$strOSDataStoreURL$strBaseOption/$strBaseOption.vmdk"
      Write-Host "Removing PowerCLI snapin (Required for multiple cmdlets)"
      Remove-PSSnapin VMWare.VimAutomation.Core | Out-Null
      # ---------------------------------------------
      Write-Host "Copying source content"
      Copy-Item $strWorkingDirOrig\*.* -Destination $strWorkingDirClone\
      Write-Host "Customizing file configurations"
      Get-ChildItem $strWorkingDirClone -Recurse -Include *.* | ForEach-Object {
            (Get-Content $_) | ForEach-Object {
                  $_ -Replace $strBaseOption, $strVMClient `
                        -Replace "-000001", "" `
                        -Replace "-delta", "_Delta" `
                        -Replace '^disk.+$', "" `
                        -Replace '^ethernet.+$', "" `
                        -Replace '^evcCompatibilityMode.+$', "" `
                        -Replace '^guestCPUID.+$', "" `
                        -Replace '^hostCPUID.+$', "" `
                        -Replace '^replay.+$', "" `
                        -Replace '^sched.+$', "" `
                        -Replace '^toolsInstallManager.+$', "" `
                        -Replace '^unity.+$', "" `
                        -Replace '^userCPUID.+$', "" `
                        -Replace '^vm.+$', "" `
                        -Replace '^vmotion.+$', ""
                  } | Set-Content $_
            (Get-Content $_) | ForEach-Object {
                  $_ -Replace "parentFileNameHint=""$strVMClient.vmdk""", "parentFileNameHint=""$strParentFileNameHint"""
                  } | Set-Content $_
            }
      # ---------------------------------------------
      Write-Host "Naming files as required"
      Get-ChildItem "$strWorkingDirClone" -Recurse -Include *.* | Rename-Item -NewName {
            $_.Name -Replace $strBaseOption, $strVMClient `
                  -Replace "-000001", "" `
                  -Replace "-delta", "_Delta"
            }
      # ---------------------------------------------
      Write-Host "Reloading PowerCLI snapin and assemblies"
      Add-PSSnapin VMWare.VimAutomation.Core | Out-Null
      [Reflection.Assembly]::LoadWithPartialName("vmware.vim") | Out-Null
            Write-Host "Connecting to server instance $strVCenterHost"            
            Connect-VIServer -Server $strVCenterHost -User "$strUserName" -Password "$strPassword" -WarningAction SilentlyContinue | Out-Null
            Write-Host "Gathering datastore object"            
            $objDataStore = Get-Datastore $strOSDataStore
            Write-Host "Adding local drive reference for datastore access"
            New-PSDrive -Location $objDataStore -Name "DataStore" -PSProvider VimDatastore -Root "\"
                  $strVMClientPath = "DataStore:\" + $strVMClient
                  If (!(Test-Path -Path "$strVMClientPath" )){
                            New-Item -ItemType Directory -Path $strVMClientPath
                  }
                  Write-Host "Gathering updated files"                  
                  $arrRequiredFiles = Get-ChildItem $strWorkingDirClone -Recurse -Include *.*
                  Write-Host "Copying required files from working directory to the datastore"
                  Copy-DataStoreItem $arrRequiredFiles $strVMClientPath -Force
                  Write-Host "Cleaning up temporary working directory"
                  Remove-Item $strWorkingDir\$strVMClient -Force -Recurse
            Write-Host "Removing local drive reference to datastore"
            Remove-PSDrive "DataStore" | Out-Null
            Write-Host "Determining least taxed cluster node for virtual machine placement"
            $strLeastTaxedHost = Get-VMhost | Select Name,CpuUsageMhz | Sort-Object CpuUsageMhz -Descending | Select -First 1
            Write-Host "Collecting datastore information"
            ForEach ($strStore In Get-Datastore $strOSDataStore) {
                  $objDataStoreInstance = Get-Datastore -Name $strStore | %{Get-View $_.Id}
                  $objSearchSpec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec
                  $objSearchSpec.matchpattern = "$strVMClient.vmx"
                  $strOSDataStoreInstanceBrowser = Get-View $objDataStoreInstance.Browser
                  $strOSDataStorePath = "[" + $objDataStoreInstance.Summary.Name + "]"
                   Write-Host "Gathering datastore view on vmx path"
                  $arrSearchResults = $strOSDataStoreInstanceBrowser.SearchDatastoreSubFolders($strOSDataStorePath, $objSearchSpec) | Where {$_.FolderPath -NotMatch ".snapshot"} | %{$_.FolderPath + ($_.File | Select Path).Path}
                  Write-Host "Registering virtual machine with vCenter"
                  ForEach ($strVMXFile in $arrSearchResults) {
                        Write-Host "Configuring the new virtual machine with the following information:"
                        Write-Host "Most eligible host:  $strLeastTaxedHost"
                        Write-Host "Datastore location:  $strOSDataStoreVMFolder"
                        Write-Host "VMX file:  $strVMXFile"
                        New-VM -VMFilePath $strVMXFile -VMHost $strLeastTaxedHost.Name -Location $strOSDataStoreVMFolder -RunAsync | Out-Null
                        }
                  }
            Write-Host "Holding process for virtual machine registration"
            Start-Sleep -s 10
            Write-Host "Configuring basic settings"
            Get-VM $strVMClient | Set-VM -MemoryMB $strMemoryOption -NumCPU $intProcOption -Confirm:$False -WarningAction SilentlyContinue | Out-Null
            Write-Host "Configuring network adapter"
            Get-VM $strVMClient | New-NetworkAdapter -NetworkName "$strNetworkOption" -StartConnected -WakeOnLan -Type $strNicType -Confirm:$False -WarningAction SilentlyContinue | Out-Null
            If ($strSecondaryHDChoice -eq "Yes") {
                  Write-Host "Adding secondary hard drive"
                  New-HardDisk -VM $strVMClient -CapacityGB 300 -DataStore $strSecondaryDataStore -StorageFormat Thin -Persistence persistent -WarningAction SilentlyContinue | Out-Null
            }
            Write-Host "Starting virtual machine"
            Get-Vm $strVMClient | Start-VM -ErrorAction SilentlyContinue | Out-Null
            Get-VMQuestion -VM $strVMClient | Set-VMQuestion -Option "button.uuid.copiedTheVM" -Confirm:$False
            Write-Host "Removing PowerCLI snapin"
      Remove-PSSnapin VMWare.VimAutomation.Core
      Write-Host "Process complete"

# ---------------------------------------------
0
Comment
Question by:usslindstrom
  • 2
  • 2
4 Comments
 
LVL 117

Expert Comment

by:Andrew Hancock (VMware vExpert / EE MVE)
Comment Utility
So I assume from reading your scripts you have created Linked Clones without the use of VMware Horizon View - which is the only supported environment for using Linked Clones?

Any other function is a hack job and hence in supported.
0
 
LVL 5

Author Comment

by:usslindstrom
Comment Utility
Understood.  I'm not looking for confirmation on what was created would be supported officially by VMWare.  - Otherwise this question would have been posted within the confines of support.
0
 
LVL 117

Accepted Solution

by:
Andrew Hancock (VMware vExpert / EE MVE) earned 500 total points
Comment Utility
Your plan is sound and will work.

But make sure you have a backup.

Sorry mobile at present cannot type much!
0
 
LVL 5

Author Closing Comment

by:usslindstrom
Comment Utility
Perfect.  - Thanks for the assistance.  :)

Will do on the idea of making sure everything important is backed up first.  Thanks.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

#Citrix #XenApp #Citrix Scout #Citrix Insight Services #Microsoft VMMAP #Microsoft ADEXPLORE #Microsoft RAMMAP #Microsoft TCPVIEW #Microsoft AUTORUNS #Microsoft PROCESS EXPLORER #Microsoft PROCESS MONITOR
Create your own, high-performance VM backup appliance by installing NAKIVO Backup & Replication directly onto a Synology NAS!
This video shows you how to use a vSphere client to connect to your ESX host as the root user. Demonstrates the basic connection of bypassing certification set up. Demonstrates how to access the traditional view to begin managing your virtual mac…
In this video tutorial I show you the main steps to install and configure  a VMware ESXi6.0 server. The video has my comments as text on the screen and you can pause anytime when needed. Hope this will be helpful. Verify that your hardware and BIO…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now