Skip to content

Instantly share code, notes, and snippets.

@vMarkusK
Last active April 20, 2016 08:13
Show Gist options
  • Save vMarkusK/592a75a00803d6dceb99d5dcf7b7ec39 to your computer and use it in GitHub Desktop.
Save vMarkusK/592a75a00803d6dceb99d5dcf7b7ec39 to your computer and use it in GitHub Desktop.
Moves a VM betwenn vSphere Datacenters. Changes Host, Datastore and Cluster.
<#
.SYNOPSIS
Moves a VM betwenn vSphere Datacenters
.DESCRIPTION
Changes Host, Datastore and Cluster.
.EXAMPLE
myMove-VM.ps1 -VMname "yourVM" -newCluster "yourCluster" -NewDS "yourDS*" -VIServer "yourvCenter.lan.local"
.PARAMETER -VMname yourVM
Specify the VM Name in vCenter Inventory
(yourVM).
.PARAMETER -newCluster yourCluster
Specify the Cluster Name in vCenter Inventory
(yourCluster).
.PARAMETER -NewDS yourDS
Specify the Datsore Wildcard-Name in vCenter Inventory
(yourDS*).
.PARAMETER -VIServer yourvCenter.lan.local
Specify the vCenter FQDN
(yourvCenter.lan.local).
.Notes
NAME: myMove-VM.ps1
LASTEDIT: 04/19/2016
VERSION: 1.0
KEYWORDS: Move VMs
.Link
https://mycloudrevolution.wordpress.com/
#Requires PS -Version 2.0
#>
[cmdletbinding()]
param(
[Parameter(Position=0, Mandatory=$true)]
[string] $VMname,
[Parameter(Position=1, Mandatory=$true)]
[string] $newCluster,
[Parameter(Position=2, Mandatory=$true)]
[string] $NewDS,
[Parameter(Position=3, Mandatory=$true)]
[string] $VIServer
)
# Start Load VMware Snapin (if not already loaded)
if (!(Get-PSSnapin -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) {
if (!(Add-PSSnapin -PassThru VMware.VimAutomation.Core)) {
# Error out if loading fails
Write-Error "ERROR: Cannot load the VMware Snapin. Is the PowerCLI installed?"
Exit
}
}
# End Load VMware Snapin (if not already loaded)
# Start Functions
function Wait-VMPowerState {
<#
.SYNOPSIS
Changes PowerState of a VMware VM and waits for operation
to complete.
.DESCRIPTION
Turns a VMware VM on or off and waits for the operation to complete. Usefull for scripts or instances where a VM needs to be in a given state before the script continues. Returns changed Get-VM output.
.PARAMETER VMName
The name of a VMware VM. You must already be connected to a VIServer.
.PARAMETER Operation
Accepts UP or DOWN as input. If the VM is already in the
requested state the function skips powerstate operations
and exits.
.EXAMPLE
C:\PS> Wait-VMPowerState -VMName MyVM -Operation up
.EXAMPLE
C:\PS> $list = get-content .\listofVMs.txt
C:\PS> $list | % { Wait-VMPowerState -VMName $_ -Operation down }
.EXAMPLE
C:\PS> $vm = Wait-VMPowerState -VMName MyVM -Operation down
C:\PS> $vm | set-vm -MemoryMB 4096
C:\PS> Wait-VMPowerState -VMName $vm.Name -Operation up
.INPUTS
System.String,System.String
.NOTES
Requires PowerCLI module. This function has been tested with
PowerShell v2.0, v3.0 CTP and PowerCLI snapin v5.0.
#>
[CmdletBinding()]
Param(
# The name of a VM
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=0)]
$VMName,
# The operation (up or down)
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet("Up","Down")]
$Operation
)
begin{
$vm = get-vm -Name $vmname
}
process{
switch ($operation) {
down {
if ($vm.PowerState -eq "PoweredOn") {
Write-Verbose "Shutting Down $vmname"
$vm | Stop-VMGuest -Confirm:$false
#Wait for Shutdown to complete
do {
#Wait 5 seconds
Start-Sleep -s 5
#Check the power status
$vm = Get-VM -Name $vmname
$status = $vm.PowerState
}until($status -eq "PoweredOff")
}
elseif ($vm.PowerState -eq "PoweredOff") {
Write-Verbose "$vmname is powered down"
}
}
up {
if ($vm.PowerState -eq "PoweredOff") {
Write-Verbose "Starting VM $vmname"
$vm | Start-VM -Confirm:$false
#Wait for startup to complete
do {
#Wait 5 seconds
Start-Sleep -s 5
#Check the power status
$vm = Get-VM -Name $vmname
$status = $vm.PowerState
}until($status -eq "PoweredOn")
}
elseif ($vm.PowerState -eq "PoweredOn") {
Write-Verbose "$vmname is powered up"
}
}
}
}
end{
$vm = Get-VM -Name $vmname
$vm
}
}
# End Functions
# Start vCenter Connection
Write-Host "Starting to Process vCenter Connection to " $VIServer " ..."-ForegroundColor Magenta
$OpenConnection = $global:DefaultVIServers | where { $_.Name -eq $VIServer }
if($OpenConnection.IsConnected) {
Write-Host "vCenter is Already Connected..." -ForegroundColor Yellow
$VIConnection = $OpenConnection
} else {
Write-Host "Connecting vCenter..."
$VIConnection = Connect-VIServer -Server $VIServer
}
if (-not $VIConnection.IsConnected) {
Write-Error "Error: vCenter Connection Failed"
Exit
}
# End vCenter Connection
# Start Dynamic Definitions
$DestCluster = get-Cluster -Name $newCluster
$DestRP = $DestCluster | Get-ResourcePool
$DestHost = $DestCluster | Get-VMHost | sort MemoryUsageGB | Select-Object -First 1
$DestDS = $DestHost | Get-Datastore | where {$_.Name -like $NewDS -and $_.State -eq "Available" -and $_.Accessible -eq "True"} | sort FreeSpaceGB -Descending | Select-Object -First 1
$myVM = Get-VM -Name $VMname
# End Dynamic Definitions
# Start Move-VM
Wait-VMPowerState -VMName $myVM.Name -Operation down
$NetworkAdapter = $myVM | Get-NetworkAdapter
foreach ($Adapter in $NetworkAdapter){
$Adapter | Set-NetworkAdapter -StartConnected:$false -Confirm:$false
}
$spec = New-Object VMware.Vim.VirtualMachineRelocateSpec
$spec.Datastore = $DestDS.ExtensionData.MoRef
$spec.Host = $DestHost.ExtensionData.MoRef
$spec.Pool = $DestRP.ExtensionData.MoRef
$myVM.ExtensionData.RelocateVM($spec,"defaultPriority")
foreach ($Adapter in $NetworkAdapter){
$Adapter | Set-NetworkAdapter -NetworkName $Adapter.NetworkName -StartConnected:$true -Confirm:$false
}
Wait-VMPowerState -VMName $myVM.Name -Operation up
# End Move-VM
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment