Reputation: 444
I need to script up some things in PowerCLI (VMWare's bolt on to PowerShell). Basically we have a server cluster with three hosts. Each host has multiple virtual switches. Each virtual switch has multiple vlans ('port groups' in VMWare speak). I need to audit the fact that the same port groups exist on each host (so things keep working if the VM is moved).
Step 1 to achieving this is would be to know that the port group name exists on each of the three host machines.
I'm falling over with how to filter some objects out of all the ones returned by a cmdlet, based on number of results returned from a property of those objects. I then need to perform further operations with original object type that passes the filter test to go on down the pipeline.
To give some specifics, this an example showing 'Some PortGroup Name' and the three hosts it exists on (and as a bonus, the vSwitch):
Get-VirtualPortGroup -Name 'Some PortGroup Name' |
Select-Object Name, VMHostID, VirtualSwitchId
produces the output
Name VMHostId VirtualSwitchId ---- -------- --------------- Some PortGroup Name HostSystem-host-29459 key-vim.host.VirtualSwitch-vSwitch6 Some PortGroup Name HostSystem-host-29463 key-vim.host.VirtualSwitch-vSwitch6 Some PortGroup Name HostSystem-host-29471 key-vim.host.VirtualSwitch-vSwitch6
Instead of 3, I'm starting with the 1849 port group names that are being returned by Get-VirtualPortGroup
. I need a pipeline to whittle the number of VirtualPortGroup objects down to a collection consisting of only those objects where a count of the 'VMHostId' property is less than 3, and pass the remaining VirtualPortGroup objects down the pipeline for further processing.
This seems simple enough to do. I'm still failing though.
The following almost works. Piping it to measure shows a count of 229, instead of the original 1849 (so it's definitely filtered a lot out, and is possibly correctly returning the subset I'm after...?). The problem is, the object type is now a 'Group' or something at this point in the pipeline, and doesn't have all the properties and methods of the original Get-VirtualPortGroup
objects.
Get-VirtualPortGroup |
Group-Object -Property Name |
Where-Object $_.Count -lt 3
Bolting a | Select-Object -ExpandProperty Group
to the end of the above seemed promising, except it then seems to return the entire collection of Get-VirtualPortGroup
objects as though I had done no filtering in there at all....
Am I doing something fundamentally wrong?
How can I filter out objects based on the count of the number of results returned by a specific property of an object, but still pass the original object type down the pipe?
Upvotes: 3
Views: 285
Reputation: 200443
Your approach is correct, but you got the Where-Object
syntax wrong. The abbreviated syntax is:
Where-Object <property> <op> <value>
without the current object variable ($_
). In your case that would be:
Where-Object Count -lt 3
Otherwise you must use scriptblock notation:
Where-Object { $_.Count -lt 3 }
This should do what you want:
Get-VirtualPortGroup |
Group-Object -Property Name |
Where-Object { $_.Count -lt 3 } |
Select-Object -Expand Group
Upvotes: 3