The Surly Admin

Father, husband, IT Pro, cancer survivor

Count Unique OS’s Per vCenter

Saw a fun little challenge from The Ginger Ninja, here.  The idea was to use PowerCLI and find out how many unique OS’s you have on your Virtual Center server.  Of course, this requires you have a VMware environment, so for the rest of you–sorry!

Using Counters

One of the interesting side effects of PowerShell is that as I’ve gotten better at it I very rarely use counters.  The classic For/Next loop falls in this category too.  It’s certainly nice to have in your arsenal but very rarely required.  You also want to be careful not to over massage your data–you’ll see what I mean later.

The more I got to understanding this code the more I realized I could replicate the output into a single line of code!

But before I do, let me just say something that my colleague’s at work have heard me say many times.  If a script works, it’s a good script.  What we want is a final output of the data we need, or the result we want.  Now, could it be better?  Absolutely, and we should always be open to new techniques and ways of thinking.

Thinking in Objects

You’ll hear this a hundred times as you work with PowerShell.  Everything is objects, you need to output objects, you need to think in objects.  Maybe another way of thinking about it is consider an array filled with your object in it as a SQL database.  Ideally you want all the information you need in that database–all of it–and then when you need to report off of it you  Select, Where and Sort you way through it.  You also want to limit the number of times you have to iterate through your data, and I think that’s where Ninja’s script could use the most improvement.

The first thing the script does is Get-VMHost, then get all of the VM’s from each host and store the OS name in an array.  Later uses Select with the -Unique parameter to get that perfect list.  But notice in the output that we never use Host in the output, so why go by each host?  You can just Get-VM and get all the VM’s in your vCenter.

The second thing this script does, is after it has the OS names it sets up a loop on each OS name, and then uses Where to limit the list to just that OS and get’s it count.  But if you have 20-30 OS’s, and 2000-3000 VM’s, you’re going back through that data a lot.  Can we make it easier?  Turns out we can.

Don’t forget about Group-Object

Group-Object is a great cmdlet for going through a dataset and grouping objects based on the property you tell it too.  One of the nice side effects of the cmdlet?  It also gives you a count of each object in that group.  So if we Group-Object our VM list on the OS property name it will do all of the work for us.  Remember, our final output is OS and count.  Ninja actually has vCenter too but I thought it would be more interesting to do it for just one at this point.

Here’s the clip, and I’ll do a quick breakdown of how I got there

Get-VM |
Get-View |
Select @{Name="OS";Expression={ $_.Summary.Config.GuestFullName }} |
Group OS |
Sort Name |
Select Name,@{Name="Total VMs";Expression={ $_.Count }}

As I mentioned above, Get-VM get’s all of the VM’s but that doesn’t contain the information I need, so piping into Get-View does that for me.  Since I only really need the Operating System from the object, and it’s relatively buried in the object I decided to do a calculated field for OS and it’s value.

From there I pipe these results to Group OS which will give me output like so:


In this example I limited the output to just the first 20 VM’s because we have a lot of VM’s.  The key properties we’re interested in here are Name and Count.  Next in the pipeline is a Sort because I like tidy output, and then the last step is piping into another Select with more calculated fields.  I’m just renaming Count to “Total VMs” here.

Here’s the final output:


Get-VM |
Get-View |
Select @{Name="OS";Expression={ $_.Summary.Config.GuestFullName }} |
Group OS |
Sort Name |
Select Name,@{Name="Total VMs";Expression={ $_.Count }}


January 16, 2016 - Posted by | PowerShell | ,

No comments yet.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: