-
Notifications
You must be signed in to change notification settings - Fork 6
/
Evacuate-VMHost.ps1
118 lines (76 loc) · 4 KB
/
Evacuate-VMHost.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
Function Evacuate-VMHost {
param (
[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$True,ValueFromPipelineByPropertyname=$True)]
[VMware.VimAutomation.ViCore.Types.V1.Inventory.VMHost]
$VMHost,
[ValidateRange(1,100)]
[int]
$VMHostMaxCPUUsagePercent = 75,
[ValidateRange(1,100)]
[int]
$VMHostMaxMEMUsagePercent = 75,
[int]
$VMHostMaxVCpuPerCore = 9,
[VMware.VimAutomation.ViCore.Types.V1.Inventory.VMHost[]]
$ExcludedVMHost,
[VMware.VimAutomation.ViCore.types.V1.Inventory.VirtualMachine[]]
$ExcludedVM,
[switch]
$fullyAutomated,
[switch]
$Whatif
)
Try {
IF ($VMHost.connectionstate -eq "connected") {
$VM = $VMHost | Get-VM | where {$_ -notin $ExcludedVM}
$VM | where powerstate -eq poweredon | ForEach-Object {
$CurVM = $_
$PossibleHost = Get-VMHost `
| Where name -ne $VMHost.name `
| where {$_ -notin $ExcludedVMHost} `
| where connectionstate -eq "connected" `
| where {(Compare-Object $CurVM.ExtensionData.network.value $_.ExtensionData.network.value).sideindicator -notcontains "<="}
$i = 0
$choice = "a"
$selectedVMHost = $PossibleHost | ForEach-Object {
$i++
$HostVM = $_ | get-vm | where powerstate -eq poweredon
[pscustomobject]@{
id = $i
name = $_.name
"ProjectedCpuUsage" = [math]::round(($_.CpuUsageMhz + $CurVM.ExtensionData.Runtime.MaxCpuUsage) / $_.CpuTotalMhz * 100,1)
"ProjectedMemUsage" = [math]::round(($_.MemoryUsageMB + $CurVM.memoryMB) / $_.MemoryTotalMB * 100,1)
"ProjectedVCPUperCORE" =[math]::round(($HostVM | Measure-Object -Property numcpu -Sum).sum / $_.NumCpu,1)
"Projected#LiveVM" = $HostVM.count + 1
}
} | where {$_.ProjectedCpuUsage -lt $VMHostMaxCPUUsagePercent -and $_.ProjectedMemUsage -lt $VMHostMaxMEMUsagePercent -and $_.ProjectedVCPUperCORE -lt $VMHostMaxVCpuPerCore}
IF ($selectedVMHost) {
$BestVMHost = $selectedVMHost | where id -eq ($selectedVMHost | select id,@{l="sum";e={$_.ProjectedCpuUsage + $_.ProjectedMemUsage}} | Sort-Object sum | select -First 1).id
($selectedVMHost | where id -eq $BestVMHost.id).id = "*"
IF (!$fullyAutomated) {
Clear-Host
$_ | select name,powerstate,numcpu,memorygb
$selectedVMHost | Sort-Object id | ft -au
Write-Host "Select host manually by its ID"
Write-Host "Press enter to follow the recommendation ( * )"
Write-Host "Enter N to skip this VM"
While ($choice -notin @("","n") -and $choice -notin (1..$i)) { $choice = Read-Host " " }
IF (!$Choice) {$selectedVMHost = $BestVMHost}
ELSEIF ($choice -eq "n") {Write-Warning "$($CurVM.name) skipped"}
ELSE {$selectedVMHost = $selectedVMHost | where id -eq $Choice}
} ELSE {
$selectedVMHost = $BestVMHost
}
IF ($choice -ne "n") {
Write-Host "$($CurVM.name) moving to $($selectedVMHost.name)" -ForegroundColor green
$params = @{VM = $_ ; Destination = get-vmhost $selectedVMHost.name}
IF ($Whatif) {$params.Add('whatif', $true)}
Move-VM @params | Out-Null
}
} ELSE {Write-Warning "There is no host capable of fulfilling the destination resource requirements"}
}
} ELSE {Write-warning "$($VMHost.name) is in a $($VMHost.connectionstate) state"}
} CATCH {
Write-Error $_.Exception -ErrorAction stop
}
}