What I am trying to achieve
I am writing a script that will run every hour and will send an email if certain VMs have been found running on the same vHost. I don't really care where each VM runs as long as one of its other VMs are not on the same vHost. The groupings are currently 4 VMs but I want it to work with N VMs in a group.
Firstly I define my groups of VMs like so:
$group1 = @("VM01", "VM02", "VM03", "VM04")
$group2 = @("SERVERA", "SERVER2")
$group3 = @("WIN01", "WIN02", "WIN03")
$groups = @($group1, $group2, $group3)
I can then do a ForEach
on $groups
and walk through each group in turn retrieving the name of the VMHost the VM is on:
ForEach($group in $groups) {
$vmhosts = New-Object 'string[]' $group.Length
For($i=0; $i -le ($group.Length -1); $i++) {
$vmhosts[$i] = Get-VM -Name $group[$i] | Get-VMHost
}
}
This gives me the IP/hostname of the VMhost into the array $vmhosts
with position matching the index of the VM in its group array.
This is where I am struggling to figure out a way to determine if any VMs are on the same VMHost and report that in my email with text like the following for each VM on the same VMHost within a group (but reports on all groups):
VM01 is on the same VMHostas VM02
VM01 is on the same VMHostas VM03
VM02 is on the same VMHostas VM03
WIN02 is on the same VMHost as WIN03
If no group of VMs are on the same VMHosts then it simply returns, "All VMs are separated correctly."
What I have tried so far
I tried to retrieve the unique VMHost from $vmhosts
with:
$unique = $vmhosts | Select -Unique
But then I need to know when VMs it was on that VMHost returned. So I tried to locate it in the $vmhosts
which worked with 3 VMs but when expanded to 4 it fails to return anything.
I'm pretty sure this could be done much better....
How about
$vmGrp1 = @("VM01", "VM02", "VM03", "VM04")
$vmGrp2 = @("SERVERA", "SERVER2")
$vmGrp3 = @("WIN01", "WIN02", "WIN03")
$vmGrps = @($vmGrp1, $vmGrp2, $vmGrp3)
$finds = @()
foreach ($vmGrp in $vmGrps)
{
$vms = get-vm $vmGrp
$HostGrps = $vms | Group-Object @{e={$_.vmhost.name}}
$finds += $HostGrps | % {if ($_.Count -gt 1) {$_.Name + " has " + ( $_.Group | Select -ExpandProperty Name) }} # this breaks in PS v2: + $_.Group.Name}}
}
if ($finds) {$finds} else {"All VMs are separated correctly."}