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:
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
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.
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.
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).
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.
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
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.
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}}
hi would you please send me acopy of your code?
Script works like a charm…. just had an issue with the copy. Thanks a lot!
Sure thing, drop me an email on ajw.renouf at gmail.com and I will send it over.
Possibly, do you mind saving this as a .ps1 or .txt and I can give it another shot?
Did the code copy ok? Looks like a copy and paste issue?
Im getting an error on line 2 char 2:
Missing expression after unary operator ‘-‘.
At :line:2 char:2
+ -V <<<< alue {