Pages

Thursday 25 July 2013

VM Migration Script

Hi Guys!

Hopefully this is the first of many posts!

So I've been working for a client who had a requirement to migrate their VMWare environment from a third party provider to a completely separate,  in-house VMWare environment.  Obviously we wanted to make this transition as easy as possible, so out came PowerCLI!

The core of this script relies heavily on LucD's great Raiders Of The Lost VMX post:

The environment is NFS based and we were lucky enough that we had access to the 3rd-Parties NFS datastores. We simply mounted their datastores into our environment so we could view the datastores.
The 3rd party guys powered down the VMs and once giving us the thumbs up, we ran the script. Based on the VMs listed in the CSV in the $Path = "C:\DATA\Scripts\VM_Migration\vmlist.csv" variable a search is performed on the datastores.
We then perform a series of additional tasks:
  • Error checking. Is the VM now listed in the inventory properly? Confirmation written to a log on the script users desktop.
  • Changes the vmnic to a hard set network name (It would be trivial to feed this information via a variable but in my case the we were migrating to were all the almost all the same)
  • Upgrades the VM hardware to hardware version 9. (They were running 4.1 still)
  • Powers the VM on (and answers the VM question you're prompted with)
The scope is there to perform all sorts of additional tasks by adding simple one liners (Upgrading VMtools!) however in this case it's all that was needed.

Here is my script:

#######################################################################


# Script Name: VMMigration.ps1
# Purpose: To migrate VMs from on VM environment, to another 
#environment based on only VM name
#
# Created by: Chris Lawrence
# Date: 10/06/2013
#######################################################################
 

# Set variables
#-----------------



Write-host
 -ForegroundColor Green "

Please Note!


 
###################################################################
# It is a pre-requisite of this script that the VM names match #
# the VMX files exactly. If they do not then please press Ctrl-C #
# and rectify prior to running Script. #
# Please make sure that the list of VMs is in a CSV file and is #
# available in C:\DATA\Scripts\VM_Migration\ Hit ENTER to continue#
# Also please REMOVE any trailing spaces from the vmlist.csv! #
###################################################################"

Read-Host
 
$Administrator = [Environment]::UserName
$Date1 = Get-Date -format d_M_yyyy
$Path = "C:\DATA\Scripts\VM_Migration" 

$VMlist = get-content -path "$Path\VMlist.csv"
 #Gets a list of all connected datastores with the exception of local ones



$DatastoreList = Get-Datastore | where {$_.Name -notmatch "Local" 

$Cluster = Read-host "Which Cluster is this batch of Virtual Machines to be host in?
 
Please make sure that you type the cluster name EXACTLY as in the inventory"



$VMFolder = Get-Datacenter -Name "**Your Datacentre**" | Get-Folder -Type VM -Name "Discovered Virtual Machine"
 


 

Start-Transcript -Path "C:\Users\$Administrator\Desktop\PowerCliTranscript_$Administrator_$Date1.log"
 
#This preps the variable for string input



$SearchResult
= @()
ForEach
($NFSDS in $DatastoreList) { 

$ds = Get-Datastore -Name $NFSDS | %{Get-View $_.Id}
 $SearchSpec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec
 $SearchSpec.matchpattern = "*.vmx"
 $dsBrowser = Get-View $ds.browser
 $DatastorePath = "[" + $ds.Summary.Name + "]"
 $SearchResult += $dsBrowser.SearchDatastoreSubFolders($DatastorePath, $SearchSpec) | where {$_.FolderPath -notmatch ".snapshot"} | %{$_.FolderPath + ($_.File | select Path).Path}
 }



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


 
#Cross references the inputted list of VMs with the list of VMX file locations in variable $Searchresult to produce a list of relevant VMX file locations.

#This preps the variable for string input



$VMXPath
= @()
ForEach
($VM in $vmlist) {
$VMXPath += $Searchresult -match "$VM.vmx"
}


 

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


 

Foreach
($VMFilepath in $VMXPath) {
 
#Selects a random ESX server for the VM to be hosted upon (You can't select the cluster in PowerCLI). This should allow DRS enough time to level out the resource load.



$ESXHost = Get-Cluster $Cluster | Get-VMHost | where {$_.Powerstate -eq "PoweredOn"}
 
 

$ESXHost = Get-Random -InputObject $esxhost
 

#Adds the vmx file to the the inventory


 

New-VM -VMFilePath $VMFilepath -VMHost $ESXHost -Location $VMFolder -RunAsync
 

Write-Host -ForegroundColor Green "Added $VMFilePath to the vCenter Inventory"
 
Write-Host -ForegroundColor Green "A log entry has been added to VM_Migration_$Administrator_$Date1.log on the desktop"
 
 

$Date = Get-Date
 

Out-File -Append -InputObject "$Date $Administrator $VMFilepath added to inventory" -Encoding Unicode -FilePath C:\Users\$Administrator\Desktop\VM_Migration_$Administrator_$Date1.log
 

start-sleep -seconds 15
 
}



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


#Error checking. Confirms that each VM is now listed in the inventory and writes to the log file accordingly.

Foreach


 
  

($VM in $VMList) {
  

$Date = Get-date
 
 

$VMCheck = get-vm | %{$_.Name -Contains "$VM"}
 
If


 

(
 
$VMCheck


 
 

-contains "True" ) {write-Output -InputObject "$Date : $VM added correctly to inventory. Migration success!" >> "C:\Users\$Administrator\Desktop\VM_Migration_$Administrator_$Date1.log"}
 
ELSE



{


 

write-Output -InputObject "$Date : $VM migration ERROR!" >> "C:\Users\$Administrator\Desktop\VM_Migration_$Administrator_$Date1.log"}
 
}
 

Write-host -ForegroundColor Green "
 
Check the Log File. The next section attempts to power on the


 
Virtual Machines. Hit Enter to continue"
 

  Read-Host


 

Write-host


 

-ForegroundColor Green "
Powering on VMs..."


 

 ForEach ($VM in $VMlist) {
  Get-VM -Name $VM | Get-NetworkAdapter | Set-NetworkAdapter -NetworkName "**Your VLAN**" -Confirm:$False
Set-VM -VM $VM -Version v9 -Confirm:$False
 Start-VM -VM $VM -Confirm:$False



start-sleep -seconds 15
 
Get-VM -Name $VM | Get-VMQuestion | Set-VMQuestion -Option “I moved it” -Confirm:$false
 }


 

Stop-Transcript


 
 
 
 
 

Happy Migrating!

Chris.

No comments:

Post a Comment