Hopefully, everyone knows by now that the default power plan in Windows 2008+ is “balanced” which can result in your CPUs being throttled down to 67% or even 50% power. This would be equivalent to running at full power with 2/3 or 1/2 as many CPUs. Make no mistake though, you still have to pay licenses for a100% of the CPUs. Why would you buy and license your CPUs and only use half of them? I’ve seen a lot of situations where a SQL Server was suffering from CPU bottleneck even though the workload wasn’t very big. This is a direct result of leaving the power plan at the default setting. All SQL Servers should be running the high performance plan to take advantage of all CPUs.
You can use the free CPU-Z tool from CPUID to check to see if your server currently has it’s CPU throttled back. Setting the power plan to high performance in modern servers is very easy (a few older models have to be set via the bios). Changing the power plan to high performance has an immediate effect on the CPUs without a reboot. It can be changed with half a dozen clicks. That’s fine if you need to set it on one server, but what if you have dozens or even hundreds of servers? Then you need to script it.
Changing the power plan programmatically is a little tricky because you have to query for the Scheme GUID of the apropriate plan and then set that guid to be active. If you were going to do this manually via the command line, you would use powercfg.exe to get a list of the available power plans (-list or -l switch), grab the guid for the high performance plan and then set it to the active plan using powercfg.exe (-setactive or -s switch).
Setting Power Plan
There are PowerShell examples already out there on the internet, and I’m a big fan of PowerShell. However, some situations may call for a non-PowerShell approach. I wrote a Windows script for this operation. Simply put the following script into a cmd file or bat file and call that script. I needed to set a large group of VMs to high performance power plan, but trying to do it remotely via PowerShell was getting me nowhere because the firewall was blocking it. I created a cmd file to set the firewall on the VMs (using netsh command) and threw the below command in there as well to do it all at once.
for /f "tokens=4,5 skip=1" %%a in ('powercfg -l') Do (if "%%b"=="(High" set pquid=%%a)
powercfg -s %pquid%