How can I get the number of CPU cores in Powershell?
Asked Answered
S

5

7

Suppose I'm running a (power)shell on a Windows machine.

Is there a one-liner I could use to get:

  1. The number of physical processor cores and/or
  2. The max number of in-flight threads, i.e. cores * hyper-threading factor?

Note: I want just a single number as the command output, not any headers or text.

Shay answered 6/11, 2021 at 21:29 Comment(0)
P
6

Note:

  • The answer below assumes a single processor (socket) with multiple cores.

  • Note: The following is gleaned from the documentation; I cannot personally verify it. According to documentation of the Win32_Processor CIM/WMI class, an instance of that class exists for each processor (socket), so if your system has multiple processors (each with multiple cores) installed, use something like the following to get the total count of logical cores (. NumberOfLogicalProcessors); use .NumberOfCores for the physical cores:

    $totalLogicalCores = (
     (Get-CimInstance –ClassName Win32_Processor).NumberOfLogicalProcessors |
       Measure-Object -Sum
    ).Sum
    
    • Note that there's also a .NumberOfEnabledCores property (Windows 10+, Windows Server 2016+), which refers to enabled physical cores, according to the docs. There's seemingly no distinct property for the hyperthreading multiplication factor, so in order to determine the enabled logical core count, you may have to to use .NumberOfEnabledCores * (.ThreadCount / .NumberOfCores)

Ran Turner's answer provides the crucial pointer, but can be improved in two ways:

  • The CIM cmdlets (e.g., Get-CimInstance) superseded the WMI cmdlets (e.g., Get-WmiObject) in PowerShell v3 (released in September 2012). Therefore, the WMI cmdlets should be avoided, not least because PowerShell (Core) (v6+), where all future effort will go, doesn't even have them anymore. Note that WMI still underlies the CIM cmdlets, however. For more information, see this answer.

  • Format-Table, as all Format-* cmdlets, is designed to produce for-display formatting, for the human observer, and not to output data suitable for later programmatic processing (see this answer for more information).

    • To instead create objects with a subset of the input objects' properties, use the Select-Object cmdlet. (If the output object(s) have 4 or fewer properties and aren't captured, they implicitly format as if Format-Table had been called; with 5 or more properties, it is implicitly Format-List).

Therefore:

# Creates a [pscustomobject] instance with 
# .NumberOfCores and .NumberOfLogicalProcessors properties.
$cpuInfo =
  Get-CimInstance –ClassName Win32_Processor | 
     Select-Object -Property NumberOfCores, NumberOfLogicalProcessors

# Save the values of interest in distinct variables, using a multi-assignment.
# Of course, you can also use the property values directly.
$coreCountPhysical, $coreCountLogical = $cpuInfo.NumberOfCores, $cpuInfo.NumberOfLogicalProcessors

Of course, if you're only interested in the values (CPU counts as mere numbers), you don't need the intermediate object and can omit the Select-Object call above.

As for a one-liner:

If you want a one-liner that creates distinct variables, without repeating the - costly - Get-CimInstance call, you can use an aux. variable that takes advantage of PowerShell's ability to use assignments as expressions:

$coreCountPhysical, $coreCountLogical = ($cpuInfo = Get-CimInstance -ClassName Win32_Processor).NumberOfCores, $cpuInfo.NumberOfLogicalProcessors
  • To save the numbers in distinct variables and output them (return them as a 2-element array), enclose the entire statement in (...).

  • To only output the numbers, simply omit the $coreCountPhysical, $coreCountLogical = part.

Prior answered 7/11, 2021 at 14:17 Comment(0)
E
8

You can use [Environment]::ProcessorCount to get the logical processor count. It works on non-Windows as well.

https://learn.microsoft.com/en-us/dotnet/api/system.environment.processorcount

Elanorelapid answered 24/4, 2023 at 17:7 Comment(0)
P
6

Note:

  • The answer below assumes a single processor (socket) with multiple cores.

  • Note: The following is gleaned from the documentation; I cannot personally verify it. According to documentation of the Win32_Processor CIM/WMI class, an instance of that class exists for each processor (socket), so if your system has multiple processors (each with multiple cores) installed, use something like the following to get the total count of logical cores (. NumberOfLogicalProcessors); use .NumberOfCores for the physical cores:

    $totalLogicalCores = (
     (Get-CimInstance –ClassName Win32_Processor).NumberOfLogicalProcessors |
       Measure-Object -Sum
    ).Sum
    
    • Note that there's also a .NumberOfEnabledCores property (Windows 10+, Windows Server 2016+), which refers to enabled physical cores, according to the docs. There's seemingly no distinct property for the hyperthreading multiplication factor, so in order to determine the enabled logical core count, you may have to to use .NumberOfEnabledCores * (.ThreadCount / .NumberOfCores)

Ran Turner's answer provides the crucial pointer, but can be improved in two ways:

  • The CIM cmdlets (e.g., Get-CimInstance) superseded the WMI cmdlets (e.g., Get-WmiObject) in PowerShell v3 (released in September 2012). Therefore, the WMI cmdlets should be avoided, not least because PowerShell (Core) (v6+), where all future effort will go, doesn't even have them anymore. Note that WMI still underlies the CIM cmdlets, however. For more information, see this answer.

  • Format-Table, as all Format-* cmdlets, is designed to produce for-display formatting, for the human observer, and not to output data suitable for later programmatic processing (see this answer for more information).

    • To instead create objects with a subset of the input objects' properties, use the Select-Object cmdlet. (If the output object(s) have 4 or fewer properties and aren't captured, they implicitly format as if Format-Table had been called; with 5 or more properties, it is implicitly Format-List).

Therefore:

# Creates a [pscustomobject] instance with 
# .NumberOfCores and .NumberOfLogicalProcessors properties.
$cpuInfo =
  Get-CimInstance –ClassName Win32_Processor | 
     Select-Object -Property NumberOfCores, NumberOfLogicalProcessors

# Save the values of interest in distinct variables, using a multi-assignment.
# Of course, you can also use the property values directly.
$coreCountPhysical, $coreCountLogical = $cpuInfo.NumberOfCores, $cpuInfo.NumberOfLogicalProcessors

Of course, if you're only interested in the values (CPU counts as mere numbers), you don't need the intermediate object and can omit the Select-Object call above.

As for a one-liner:

If you want a one-liner that creates distinct variables, without repeating the - costly - Get-CimInstance call, you can use an aux. variable that takes advantage of PowerShell's ability to use assignments as expressions:

$coreCountPhysical, $coreCountLogical = ($cpuInfo = Get-CimInstance -ClassName Win32_Processor).NumberOfCores, $cpuInfo.NumberOfLogicalProcessors
  • To save the numbers in distinct variables and output them (return them as a 2-element array), enclose the entire statement in (...).

  • To only output the numbers, simply omit the $coreCountPhysical, $coreCountLogical = part.

Prior answered 7/11, 2021 at 14:17 Comment(0)
A
3
$env:NUMBER_OF_PROCESSORS 

gives number of processors. Works also when you have more than one socket in use

Arborescent answered 30/11, 2022 at 13:50 Comment(1)
So, if I have 3 sockets with 5 cores per socket and a "hyperthreading factor" of 2 - what would this show me?Shay
S
2

To find out processor number of cores using PowerShell

Get-WmiObject –class Win32_processor | ft NumberOfCores,NumberOfLogicalProcessors

To find out what is the number of threads running:

(Get-Process|Select-Object -ExpandProperty Threads).Count

Sheelah answered 6/11, 2021 at 21:33 Comment(4)
As an aside: The CIM cmdlets (e.g., Get-CimInstance) superseded the WMI cmdlets (e.g., Get-WmiObject) in PowerShell v3 (released in September 2012). Therefore, the WMI cmdlets should be avoided, not least because PowerShell (Core) (v6+), where all future effort will go, doesn't even have them anymore. Note that WMI still underlies the CIM cmdlets, however. For more information, see this answer.Prior
@mklement0: So, how do I get the number of physical/logical cores using Get-CimInstance, then?Shay
Same class, and almost the exact same syntax. Run Get-Help Get-CimInstance to see the proper syntax, but it should be: Get-CimInstance -ClassName win32_processor | Select NumberofCoresDyson
Get-CimInstance –ClassName Win32_Processor | Format-Table -Property NumberOfCores,NumberOfLogicalProcessorsBorecole
B
1

There are several comments with similar answers. Get-WmiObject is deprecated. Go with Get-CimInstance. Do not use aliases in scripts. Spell commands and parameters out. Explicit is better than implicit.

Get-CimInstance –ClassName Win32_Processor | Format-Table -Property NumberOfCores,NumberOfLogicalProcessors

UPDATE:

If you want only a single number value assigned to a variable.

$NumberOfCores = (Get-CimInstance –ClassName Win32_Processor).NumberOfCores
$NumberOfLogicalProcessors = (Get-CimInstance –ClassName Win32_Processor).NumberOfLogicalProcessors
Borecole answered 7/11, 2021 at 13:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.