Number of Physical & Virtual CPU’s per host & Cluster

Recently I received a comment on an older post of mine which gave output of the number of virtual CPU’s on a host and also in a cluster, the comment asked if there was a way to export this to a text or html file which is easy enough in PowerShell.

After reading my code I was astounded at how bad it was, one thing i wish I had time for was to go back to some of my earlier code to tidy it up with the tips and tricks I have learnt over the last year and also amend it to use the new features provided to us by the PowerCLI team to make things easier.

One such feature is a cmdlet in the current release of PowerCLI (4.1 U1) (If your not sure what version you are running then just type Get-PowerCLIVersion at the prompt). 

The cmdlet I am referring to is New-VIProperty, this cmdlet allows us to add additional properties to the returned values from certain objects, for a detailed post on this cmdlet look at Luc’s great post here I can also highly recommend his list of New-VIProperty examples which is amazing and can be found here.

Basically this allows us to expand our returned objects from cmdlets to give us further information for an easy example if we run Get-VM we will receive a number of different default properties but what if we wanted something that wasn’t on the list of returned properties ?  Normally we would need to use a PowerShell expression to add this data when we select the data:

Get-VM | Select Name, @{Name="ToolsVersion";Expression={$_.ExtensionData.config.tools.ToolsVersion}}

Whilst this works there are a couple of reasons I don’t like to use it, firstly its hard to read, when teaching people about this its always a hard one to explain as it doesn’t look as English as the rest of PowerShell and I make a big deal of telling them how PowerShell is so easy to learn as it almost reads as English.

Secondly, Imagine if you have lots of code in your expression, this can start getting complicated and doesn’t really belong in the main part of your script as far as i am concerned.

So how would this look with New-VIProperty ?

New-VIProperty -Name ToolsVersion -ObjectType VirtualMachine `
    -ValueFromExtensionProperty ‘config.tools.ToolsVersion’ `
    -Force

Get-VM | Select Name, ToolsVersion

Now doesn’t this look nicer, basically we are defining the property before we run the Get-VM and therefore all the issues I mentioned above are now resolved.

Anyway, back to my original reason for writing this post – I took the original script and re-wrote it in this new format which makes it much easier to work with and is much nicer to view, below is the new code:

New-VIProperty -ObjectType VMHost -name NumvCPUs `
    -Value {
            $TotalvCPU = 0
            $Args[0] | Get-VM | Foreach {
                $TotalvCPU += $_.NumCPU
            }
            $TotalvCPU
    } -Force

New-VIProperty -ObjectType VMHost -name NumPoweredOnvCPUs `
    -Value {
            $TotalvCPU = 0
            $Args[0] | Get-VM | Where { $_.PowerState -eq "PoweredOn" } | Foreach {
                $TotalvCPU += $_.NumCPU
            }
            $TotalvCPU
    } -Force

New-VIProperty -Name NumvCPUs -ObjectType Cluster `
    -Value {
            $TotalvCPU = 0
            $Args[0] | Get-VMHost | Foreach {
                $TotalvCPU += $_.NumvCPUs
            }
            $TotalvCPU
    } `
    -Force

New-VIProperty -ObjectType Cluster -name NumPoweredOnvCPUs `
    -Value {
            $TotalvCPU = 0
            $Args[0] | Get-VMHost | Foreach {
                $TotalvCPU += $_.NumPoweredOnvCPUs
            }
            $TotalvCPU
    } -Force

New-VIProperty -Name NumCPU -ObjectType Cluster `
    -Value {
            $TotalPCPU = 0
            $Args[0] | Get-VMHost | Foreach {
                $TotalPCPU += $_.NumCPU
            }
            $TotalPCPU
    } `
    -Force

Get-VMHost | Select Name, NumCPU, NumvCPUs, NumPoweredOnvCPUs

Get-Cluster | Select Name, NumCPU, NumvCPUs, NumPoweredOnvCPUs

Which gives us a nice output of:

image

Or this can now easily be exported to a text file using Out-File or a HTML file by changing the following line:

Get-VMHost | Select Name, NumCPU, NumvCPUs, NumPoweredOnvCPUs | ConvertTo-Html | Out-File c:\Tmp\HostvCPUs.html

13 thoughts on “Number of Physical & Virtual CPU’s per host & Cluster

  1. Jibi

    Old post, I know… but curious if there is a way to do this for a datacenter that has multiple clusters. For example, pull data for clus1, clus2, and clus3 then combine all three numbers/totals for a datacenter tally.

  2. Josh

    Pretty sure the 1:3 ratio recommendation does not include hyper-threaded / logical cores as they only improve performance by ~10% so this should be fine as is.

  3. Karl

    Once again Al, excellent stuff. In your infinite free time, could you comment on how one could go about getting the logical processor count on the physical hosts? I have been using this script to help chase down nasty vCPU Ready Times, but I have to multiply the pCPU x 2 to get the actual logical host processors count (i.e. I am trying to track down my pCPU to vCPU to see how far off we are from the “voice of the industry” to maintain a 1:3 ratio).

  4. Diesel

    I have a question about lines 19-25. This piece of code $TotalvCPU += $_.NumvCPUs

    where $_ is the host name. I don’t see where NumvCPUs is a property of a host and I can’t get this to work.

  5. Hemant Patel

    Hi,

    I am having below error when execute script.
    “You must provide a value expression on the right-hand side of the ‘-‘ operator.
    At C:\healthcheck\VMCOUNT\NEW.PS1:24 char:9”

    Thanks,
    Hemant

  6. Luke

    Thank you for this, the script is excellent! Is there a good way to output the data in columns instead of a list, I’ve been playing around with this and can’t seem to figure it out.

    Again thank you much, your work is very appreciated.

  7. Mark

    How do you get\set virtual socket information for the guest OS?

    I can find total cores and total cpus but virtual sockets has been a mystery to me.

    Thanks
    -mark

    Get-VM _2008x64 | Get-View | Select Name, `
    @{N=”VirtualSockets”;E={$_.Configspec.numcpuPkgs}}, ` # Can’t find the correct location for this info
    @{N=”CoresPerSocket”;E={$_.Configspec.NumCoresPerSocket}}, `
    @{N=”vCPUs”;E={$_.Configspec.numcpus}}

  8. Justin Smith

    Script works like a charm…. just had an issue with the copy. Thanks a lot!

  9. Justin Smith

    Possibly, do you mind saving this as a .ps1 or .txt and I can give it another shot?

  10. Justin Smith

    Im getting an error on line 2 char 2:

    Missing expression after unary operator ‘-‘.
    At :line:2 char:2
    + -V <<<< alue {

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.