I don't have access to a multi-socketed computer, so I am unsure if the following will get the grand total of processors and logical processors. I assume ManagementObjectSearcher will return an instance for each socketed CPU and I just keep a running total?
int totalCPUs = 0;
int totalLogicalCPUs = 0;
ManagementObjectSearcher mos = new ManagementObjectSearcher("Select * from Win32_ComputerSystem");
foreach (var mo in mos.Get())
{
string num = mo.Properties["NumberOfProcessors"].Value.ToString();
totalCPUs += Convert.ToInt32(num);
num = mo.Properties["NumberOfLogicalProcessors"].Value.ToString();
totalLogicalCPUs += Convert.ToInt32(num);
}