jeroenburen

Migrate-Cluster

Jun 23rd, 2020 (edited)
276
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <#
  2. .SYNOPSIS
  3.     Perform steps to migrate VMs.
  4. .DESCRIPTION
  5.     Use this script to move VMs.
  6.     Possible scenarios are:
  7.     - vMotion VMs from DC1 hosts to temporary DC3 hosts, including a Storage vMotion.
  8.     - vMotion VMs from DC1 hosts to new DC3 hosts, including a Storage vMotion.
  9.     - vMotion VMs from temporary DC3 hosts to relocated AMS hosts.
  10.     - Storage vMotion from DC2 storage to new DC2 storage.
  11.     - vMotion VMs from DC2 hosts to new DC2 hosts, including a Storage vMotion
  12.     Only VMs without Raw Device Mappings (RDM) are moved.
  13.    
  14.     This script assumes the availability of the following modules:
  15.     - VMware-PowerCli
  16. .PARAMETER
  17.     - Cluster (String value with the name of the cluster) [Mandatory]
  18.     - NewCluster (String value with the name of the new cluster)
  19. .EXAMPLE
  20.     .\Migrate-Cluster.ps1 -Cluster CLS01
  21.     .\Migrate-Cluster.ps1 -Cluster CLS01 -NewCluster CLS05
  22. .NOTES
  23.     Script name:    Migrate-Cluster.ps1
  24.     Author:         Jeroen Buren
  25.     DateCreated:    19-06-2020
  26.     Version:        1.0
  27. #>
  28.  
  29. [CmdletBinding(SupportsShouldProcess=$true)]
  30.  
  31. param (
  32.     [parameter(mandatory = $true)][string]$Cluster,
  33.     [parameter(Mandatory = $false)][string]$NewCluster
  34. )
  35.  
  36. $version = "1.0"
  37.  
  38. Get-Module -Name VMware* -ListAvailable | Import-Module
  39.  
  40. ####################################################################################
  41. #                                                                                  #
  42. # Variables                                                                        #
  43. #                                                                                  #
  44. ####################################################################################
  45.  
  46. $vMotion = 0
  47. $SvMotion = 0
  48.  
  49. ####################################################################################
  50. #                                                                                  #
  51. # Functions                                                                        #
  52. #                                                                                  #
  53. ####################################################################################
  54.  
  55. function Get-ScriptDirectory {
  56.   $Invocation = (Get-Variable MyInvocation -Scope 1).Value
  57.   Split-Path $Invocation.MyCommand.Path
  58. }
  59.  
  60. # Logfile
  61. Set-Variable logFile ((Get-ScriptDirectory) + "\Migrate-Cluster.log") -Option Constant -ErrorAction SilentlyContinue
  62.  
  63. function Write-Log {
  64.   param(
  65.     [Parameter(Mandatory=$true)][String]$Message,
  66.     [Parameter(Mandatory=$true)][ValidateSet("Info","Debug","Warn","Error")][String]$Type,
  67.     [Parameter(Mandatory=$true)][ValidateSet("Console","LogFile","Both")][String]$OutputMode
  68.   )
  69.  
  70.   $dateTimeString = Get-Date -Format "yyyy-MM-dd HH:mm:sszz"
  71.   $output = ($dateTimeString + " " + $type.ToUpper() + " " + $message)
  72.   if ($outputMode -eq "Console" -OR $outputMode -eq "Both") {
  73.     Write-Host $output
  74.   }
  75.   if ($outputMode -eq "LogFile" -OR $outputMode -eq "Both") {
  76.     try {
  77.       Add-Content $logFile -Value $output -ErrorAction Stop
  78.     }
  79.     catch {
  80.       Write-Log ("Failed to write to log file: """ + $logFile + """.") -OutputMode Console -Type Error
  81.       Write-Log ("[" + $_.Exception.GetType().FullName + "] " + $_.Exception.Message) -OutputMode Console -Type Error
  82.     }
  83.   }
  84. }
  85.  
  86. function Connect_vCenter {
  87.   Clear-Host
  88.   # vCenter connection details
  89.   Write-Host `n" Getting connection details of vCenter..." -ForegroundColor Green
  90.   Write-Host `n" Enter vCenter details..."`n
  91.   $vc = Read-Host -Prompt "`tHost Name/IP address`t"
  92.   $vcuser = Read-Host -Prompt "`tUser Name`t`t"
  93.   $vcpass = Read-Host -Prompt "`tPassword`t`t" -AsSecureString
  94.   $vccreds = New-Object System.Management.Automation.PSCredential ($vcuser, $vcpass)
  95.  
  96.   # make connection to vCenter
  97.   Try {
  98.     Write-Log -Message "Connecting to vCenter." -Type Info -OutputMode LogFile
  99.     Connect-VIServer -Server $vc -Credential $vccreds -ErrorAction Stop| Out-Null
  100.     Write-Log -Message "Connection to vCenter is successful." -Type Info -OutputMode LogFile
  101.   }
  102.   Catch {
  103.     Write-Host `n" Oeps... There was an error connecting to the vCenter server..." -ForegroundColor Yellow
  104.     Write-Log -Message "There was an error connecting to the vCenter server." -Type Error -OutputMode LogFile
  105.     Pause
  106.     return
  107.   }
  108.  
  109.   # Displaying runtime information
  110.   Write-Host `n"`tConnected to vCenter Server`t: $global:defaultviserver"
  111.   Write-Host "`tSource Cluster to be migrated`t: $Cluster"
  112.   Write-Host "`tDestination Cluster`t`t: $NewCluster"`n
  113.   Pause
  114.   return
  115. }
  116.  
  117. function Remote_Migration {
  118.   Clear-Host
  119.   Write-Host `n"Moving VMs from datacenter DC1 to remote datacenter DC3..."`n
  120.   Write-Log -Message "Moving VMs from datacenter DC1 to remote datacenter DC3." -Type Info -OutputMode LogFile
  121.   foreach ($vmhost in Get-Cluster -Name $Cluster | Get-VMHost -Tag "DC1") { # Select all the DC1 hosts in the cluster
  122.     Write-Host "Starting migration for host $($vmhost.Name)..."
  123.     Write-Log -Message "Starting migration for host $($vmhost.Name)." -Type Info -OutputMode LogFile
  124.     $VMswithRDM = $vmhost | Get-VM | Where-Object {$_ | Get-HardDisk -DiskType RawPhysical,RawVirtual}
  125.     foreach ($vm in $vmhost | Get-VM | Where-Object {$_ -notin $VMswithRDM}) { # Perform steps for each VM on a host but only for VMs without RDM
  126.       Try {
  127.         $Destination_Host = Get-Cluster -Name $NewCluster | Get-VMHost -Tag "DC3" | Get-Random # Pick a random destination host from the new cluster in the DC3 datacenter
  128.         $Destination_Datastore = Get-DatastoreCluster -Tag "DC3" | Where-Object {$_.Name -like "$cluster*"} # Get a destination datastore in the DC3 datacenter
  129.         Move-VM -VM $vm -Destination $Destination_Host -Datastore $Destination_Datastore -RunAsync -ErrorAction Stop | Out-Null # Create a Move-VM task to move the VM
  130.         Write-Log -Message "Moved $($vm.Name) to $($Destination_Host.Name) and $($Destination_Datastore.Name)" -Type Info -OutputMode LogFile
  131.         }
  132.       Catch {
  133.         Write-Host " Oeps... There was an error moving VM $($vm.Name)..."
  134.         Write-Log -Message "There was an error moving VM $($vm.Name)." -Type Error -OutputMode LogFile
  135.       }
  136.     }
  137.     Write-Host "Done migrating VMs from the host $($vmhost.Name). Do you wish to continue with the next host?"
  138.     Pause
  139.   }
  140.   Write-Host "Remote migration of cluster $Cluster is finished..."
  141.   Write-Log -Message "Remote migration of cluster $Cluster is finished." -Type Info -OutputMode LogFile
  142.   Pause  
  143.   return
  144. }
  145.  
  146. function Local_Migration {
  147. #region Ask for details
  148.   Clear-Host
  149.   # Asking what type of vMotion should be performed
  150.   Write-Host `n" Getting migration details..."
  151.  
  152.   Do {
  153.     Write-host `n" In which datacenter would you like to perform the migration? ( DC2 / DC3 ) : " -NoNewLine
  154.     $Location = Read-Host
  155.     $Location = $Location.ToUpper()
  156.   } while ($Location -notin "DC2", "DC3")
  157.  
  158.   if ($Location -eq "DC2") {
  159.     Do {
  160.       Write-host `n" Would you like to perform a host migration (vMotion)? ( y / n ) : " -NoNewLine
  161.       $Readhost = Read-Host
  162.     } while ($Readhost -notin "y","n")
  163.  
  164.     Switch ($ReadHost) {
  165.       Y {$vMotion = 1}
  166.       N {$vMotion = 0}
  167.       Default {}
  168.     }
  169.     $SvMotion = 1
  170.   }
  171.  
  172.   if ($Location -eq "DC3") {
  173.     $vMotion = 1
  174.     $SvMotion = 0
  175.   }
  176. #endregion
  177.  
  178. #region DC3 vMotion
  179.   if ($Location -eq "DC3") { # Only vMotion
  180.     Clear-Host
  181.     Write-Host `n"Moving VMs in datacenter DC3 to the old DC1 hosts..."`n
  182.     Write-Log -Message "Moving VMs in datacenter DC3 to the old DC1 hosts." -Type Info -OutputMode LogFile
  183.     foreach ($vmhost in Get-Cluster -Name $Cluster | Get-VMHost -Tag "DC3") { # Select all the DC3 hosts in the cluster
  184.       Write-Host "Starting migration for host $($vmhost.Name)..."
  185.       Write-Log -Message "Starting migration for host $($vmhost.Name)." -Type Info -OutputMode LogFile
  186.       $VMswithRDM = $vmhost | Get-VM | Where-Object { $_ | Get-HardDisk -DiskType RawPhysical, RawVirtual }
  187.       foreach ($vm in $vmhost | Get-VM | Where-Object { $_ -notin $VMswithRDM }) {
  188.         # Perform steps for each VM on a host but only for VMs without RDM
  189.         Try {
  190.           $Destination_Host = Get-VMHost -Tag "DC1" | Get-Random # Get a random destination host with the DC1 tag. These are the relocated hosts from the old DC1 datacenter.
  191.           Move-VM -VM $vm -Destination $Destination_Host -RunAsync -ErrorAction Stop | Out-Null # Create a Move-VM task to move the VM
  192.           Write-Log -Message "Moved $($vm.Name) to $($Destination_Host.Name)" -Type Info -OutputMode LogFile
  193.         }
  194.         Catch {
  195.           Write-Host " Oeps... There was an error moving VM $($vm.Name)..."
  196.           Write-Log -Message "There was an error moving VM $($vm.Name)." -Type Error -OutputMode LogFile
  197.         }
  198.       }
  199.       Write-Host "Done migrating VMs from the host $($vmhost.Name). Do you wish to continue with the next host?"
  200.       Pause
  201.     }
  202.   Write-Host "Local migration of cluster $Cluster is finished..."
  203.   Write-Log -Message "Local migration of cluster $Cluster is finished." -Type Info -OutputMode LogFile
  204.   Pause  
  205.   return
  206.   }
  207. #endregion
  208.  
  209. #region DC2 storage vMotion
  210.   if (($Location -eq "DC2") -and ($vMotion -eq 0)) { # Only Storage vMotion
  211.     Clear-Host
  212.     Write-Host `n"Moving VMs in datacenter DC2 to new storage..."`n
  213.     Write-Log -Message "Moving VMs in datacenter DC2 to new storage." -Type Info -OutputMode LogFile
  214.     foreach ($vmhost in Get-Cluster -Name $Cluster | Get-VMHost -Tag "DC2") { # Select all the DC2 hosts in the cluster
  215.       Write-Host "Starting migration for host $($vmhost.Name)..."
  216.       Write-Log -Message "Starting migration for host $($vmhost.Name)." -Type Info -OutputMode LogFile
  217.       $VMswithRDM = $vmhost | Get-VM | Where-Object { $_ | Get-HardDisk -DiskType RawPhysical, RawVirtual }
  218.       foreach ($vm in $vmhost | Get-VM | Where-Object { $_ -notin $VMswithRDM }) { # Perform steps for each VM on a host but only for VMs without RDM
  219.         Try {
  220.           $Destination_Datastore = Get-DatastoreCluster -Tag "DC2" | Where-Object { $_.Name -like "$cluster*" } # Get a destination datastore in the DC2 datacenter
  221.           Move-VM -VM $vm -Datastore $Destination_Datastore -RunAsync -ErrorAction Stop | Out-Null # Create a Move-VM task to move the VM
  222.           Write-Log -Message "Moved $($vm.Name) to $($Destination_Datastore.Name)" -Type Info -OutputMode LogFile
  223.         }
  224.         Catch {
  225.           Write-Host " Oeps... There was an error moving VM $($vm.Name)..."
  226.           Write-Log -Message "There was an error moving VM $($vm.Name)." -Type Error -OutputMode LogFile
  227.         }
  228.       }
  229.       Write-Host "Done migrating VMs from the host $($vmhost.Name). Do you wish to continue with the next host?"
  230.       Pause
  231.     }
  232.   Write-Host "Local migration of cluster $Cluster is finished..."
  233.   Write-Log -Message "Local migration of cluster $Cluster is finished." -Type Info -OutputMode LogFile
  234.   Pause  
  235.   return
  236.   }
  237. #endregion
  238.  
  239. #region DC2 vMotion and Storage vMotion
  240.   if (($Location -eq "DC2") -and ($vMotion -eq 1)) { # Both vMotion and Storage vMotion
  241.     Clear-Host
  242.     Write-Host `n"Moving VMs in datacenter DC2 to new hosts and storage..."`n
  243.     Write-Log -Message "Moving VMs in datacenter DC2 to new hosts and storage." -Type Info -OutputMode LogFile
  244.     foreach ($vmhost in Get-Cluster -Name $Cluster | Get-VMHost -Tag "DC2") {
  245.       # Select all the DC2 hosts in the cluster
  246.       Write-Host "Starting migration for host $($vmhost.Name)..."
  247.       Write-Log -Message "Starting migration for host $($vmhost.Name)." -Type Info -OutputMode LogFile
  248.       $VMswithRDM = $vmhost | Get-VM | Where-Object { $_ | Get-HardDisk -DiskType RawPhysical, RawVirtual }
  249.       foreach ($vm in $vmhost | Get-VM | Where-Object { $_ -notin $VMswithRDM }) {
  250.         # Perform steps for each VM on a host but only for VMs without RDM
  251.         Try {
  252.           $Destination_Host = Get-Cluster -Name $NewCluster | Get-VMHost -Tag "DC2" | Get-Random # Pick a random destination host from the new cluster in the DC2 datacenter
  253.           $Destination_Datastore = Get-DatastoreCluster -Tag "DC2" | Where-Object { $_.Name -like "$cluster*" } # Get a destination datastore in the WSN datacenter
  254.           Move-VM -VM $vm -Destination $Destination_Host -Datastore $Destination_Datastore -RunAsync -ErrorAction Stop | Out-Null # Create a Move-VM task to move the VM
  255.           Write-Log -Message "Moved $($vm.Name) to $($Destination_Host.Name) and $($Destination_Datastore.Name)" -Type Info -OutputMode LogFile
  256.         }
  257.         Catch {
  258.           Write-Host " Oeps... There was an error moving VM $($vm.Name)..."
  259.           Write-Log -Message "There was an error moving VM $($vm.Name)." -Type Error -OutputMode LogFile
  260.         }
  261.       }
  262.       Write-Host "Done migrating VMs from the host $($vmhost.Name). Do you wish to continue with the next host?"
  263.       Pause
  264.     }
  265.   Write-Host "Local migration of cluster $Cluster is finished..."
  266.   Write-Log -Message "Local migration of cluster $Cluster is finished." -Type Info -OutputMode LogFile
  267.   Pause  
  268.   return
  269.   }
  270. #endregion
  271. }
  272.  
  273. ####################################################################################
  274. #                                                                                  #
  275. # Main code                                                                        #
  276. #                                                                                  #
  277. ####################################################################################
  278. $Cluster = $Cluster.ToUpper()
  279. if (!$NewCluster) {$NewCluster = $Cluster}
  280. $NewCluster = $NewCluster.ToUpper()
  281.  
  282. Write-Log -Message "Migration Tool Version: $version started" -Type Info -OutputMode Both
  283.  
  284. Do {
  285.   Clear-Host
  286.   Write-Host `n"            Cluster Migration Tool"
  287.   Write-Host `n"            Version $version"`n
  288.   Write-Host "Type 'q' or press enter to quit..."`n
  289.   Write-Host " 1. Connect to vCenter"
  290.   Write-Host "    Connect to vCenter Server with supplied credentials."`n
  291.   Write-Host " 2. Remote Migration"
  292.   Write-Host "    Move VMs from datacenter DC1 to remote datacenter DC3."`n
  293.   Write-Host " 3. Local Migration"
  294.   Write-Host "    Move VMs within the same location to different hosts and/or storage."`n`n
  295.   $selection = Read-Host -Prompt "Select Option "
  296.   Switch ($selection) {
  297.     "1" {Connect_vCenter}
  298.     "2" {Remote_Migration}
  299.     "3" {Local_Migration}
  300.     {($_ -like "*q*") -or ($_ -eq "")} {
  301.       Clear-Host
  302.       Write-Host `n"`tDisconnecting from vCenter Server..." -ForegroundColor Yellow
  303.       Disconnect-VIServer -erroraction ignore -Confirm:$false | Out-Null
  304.       Write-Host `n
  305.       pause
  306.       Clear-Host
  307.       exit
  308.     }
  309.     default {}
  310.   }
  311. } While ($selection -le 3)
Add Comment
Please, Sign In to add comment