Search code examples
powershellvmwarepowershell-3.0powershell-4.0powercli

Comparing two VMHostVirtualSwitches that always show equal


I am comparing a predetermined object (VMHostVirtualSwitch Name) value with all object(VMHostVirtualSwitch Names) values within a collection of objects and want the status to be "FAIL" if the objects don't match

I have written the following code so far but it doesn't seem to be working. I know the objects don't match and I should get "FAIL" as an output

$VMHostVirtualSwitch = Get-VMHostNetwork -VMHost abc.com | Select-Object VirtualSwitch*
$Cluster = Get-Cluster -VMHost abc.com 
$VMHosts = Get-Cluster $Cluster | Get-VMHost
[int]$Switchcount=0

foreach ($VMHost in $VMHosts){
  $CurrentHostVirtualSwitch = Get-VMHostNetwork -VMHost $VMHost | Select-Object VirtualSwitch*
  if ($CurrentHostVirtualSwitch -ne $VMHostVirtualSwitch) {
   $Switchcount++
  }
}
if($Switchcount -ge 1) {
Write-Output "FAIL"
}

$VMHostVirtualSwitch has the following value

VirtualSwitch
-------------
{vSwitch3} 

When I expand the $VMHostVirtualSwitch , I get the following values

Name                           NumPorts   Mtu   Notes                                             
----                           --------   ---   -----                                             
vSwitch3                       10562      2340     

Solution

  • You problem is PowerShell does not know how to compare those objects. Even if they had the same data they are technically two different objects (a blog post touches on this subject). At the end of the day if you are just comparing the names then do your comparison on just those.

    $VMHostVirtualSwitch = (Get-VMHostNetwork -VMHost abc.com).VirtualSwitch.Name
    $Cluster = Get-Cluster -VMHost abc.com 
    $VMHosts = Get-Cluster $Cluster | Get-VMHost
    [int]$Switchcount=0
    
    foreach ($VMHost in $VMHosts){
        $CurrentHostVirtualSwitch = (Get-VMHostNetwork -VMHost $VMHost).VirtualSwitch.Name
        if ($CurrentHostVirtualSwitch -ne $VMHostVirtualSwitch) {
            $Switchcount++
        }
    }
    
    if($Switchcount -ge 1) {
        Write-Output "FAIL"
    }
    

    Now you should just be comparing strings which will get you more predictable results. I have only change the variable expansion in the above example. You might have some error checking to do to account for.

    Something like this might be shorter then your loop

    $badHosts = $VMHosts | Where-Object{(Get-VMHostNetwork -VMHost $_).VirtualSwitch.Name -ne $VMHostVirtualSwitch}
    if($badHosts.count -ge 1) {
        Write-Output "FAIL"
    }
    

    Compare-Object would also be a way to go for this, especially if there was multiple properties you were comparing: example. Since we are boiling down to simple strings I think what I propose should suffice.