In a previous post, I introduced you to VM groups in Hyper-V and demonstrated how to work with them using PowerShell. I’m still working with them to see how I will incorporate them into my everyday Hyper-V work, but I already know that I wish the cmdlets for managing groups worked a little differently. But that’s not a problem. I can create my own tooling around these commands and build a solution that works for me. Let me share what I’ve come up with so far.
1. Finding Groups
As I explained last time, you can have a VM group that contains a collection of virtual machines, or nested management groups. By default, Get-VMGroup will return all groups. Yes, you can filter by name but you can’t filter by group type. If I want to see only Management groups, I need to use a PowerShell expression like this:
Get-VMGroup -computername SRV01 | where {$_.grouptype -EQ "ManagementCollectionType" }
This is not a complicated expression but it becomes tedious when I am repeatedly typing or modifying this command. This isn’t an issue in a script, but for everyday interactive work, it can be a bit much. My solution was to write a new command, Find-VMGroup, that works identically to Get-VMGroup except this version allows you to specify a group type.
![]()
Your output might vary from the screenshot but I think you get the idea. The default is to return all groups, but then you might as well use Get-VMGroup. And because the group type is coded into the function, you can use tab complete to select a value.
Interested in getting the Find-VMGroup command? I have a section on how to install the module a little further down the page.
2. Expanding Groups
Perhaps the biggest issue (and even that might be a bit strong) I had with the VM Group command is that ultimately, what I really want are the members of the group. I want to be able to use groups to do something with all of the members of that group. And by members, I mean virtual machines. It doesn’t matter to me if the group is a VM Collection or Management Collection. Show me the virtual machines!
Again, this isn’t technically difficult.
![]()
If you haven’t figured out by now I prefer simple. Getting virtual machines from a management group requires even more steps. Once again, I wrote my own command called Expand-VMGroup.
![]()
The output has been customized a bit to provide a default, formatted view. There are in fact other properties you could work with.
![]()
Depending on the command, you might be able to pipe these results to another Hyper-V command. But I know that many of the Hyper-V cmdlets will take pipeline input by value. This allows you to pass a list of virtual machine names to a command. I added a parameter to Expand-VMGroup that will write just the virtual machine names to the pipeline as a list. Now I can run commands like this:
![]()
Again, the module containing this command can be found near the end of the article and can be installed using Install-Module
3. Starting and Stopping Groups
The main reason I want to use VM groups is to start and stop groups of virtual machines all at once. I could use Expand-VMGroup and pipe results to Start-VM or Stop-VM but I decided to make specific commands for starting and stopping all virtual machine members of a group. If a member of the group is already in the targeted state, it is skipped.
![]()
The third member of this group was already running so it was skipped. Now I’ll shut down the group.
![]()
It may not seem like much but every little thing I can do to get more done with less typing and effort is worth my time. I’m using full parameter names and typing out more than I actually need to for the sake of clarity.
How Do I Get These Commands
Normally, I would show you code samples that you could use. But in this case, I think these commands are ready to use as-is. You can get the commands from my PSHyperVTools module which is free to install from the PowerShell Gallery.
Install-Module PSHyperVTools
If you haven’t installed anything before you might get a prompt to update the version of nuget. Go ahead and say yes. You’ll also be prompted if you want to install from a non-trusted repository. You aren’t installing this on a mission-critical server so you should be OK. Once installed, you can use the commands that I’ve demonstrated. They should all have help and examples.
![]()
The module is open source so if you’d like to review the code first or the README, jump over to https://github.com/jdhitsolutions/PSHyperV. There are a few other commands and features of the module that I hope to write about in a future article or two. But for now, I hope you’ll give these commands a spin and let me know what you think in the comments section below!